各种API远程线程注入的方法,分别是 远程线程注入,普通消息钩子注入,全局消息钩子注入,APC应用层异步注入,ZwCreateThreadEx强力注入,纯汇编实现的线程注入等。

简单编写DLL文件:

#include <Windows.h>

extern "C" __declspec(dllexport) void MsgBox(LPCWSTR szMsg, LPCWSTR Title)
{
MessageBox(NULL, szMsg, Title, MB_OK);
} BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
// 进程被加载后执行
break;
case DLL_THREAD_ATTACH:
// 线程被创建后加载
break;
case DLL_THREAD_DETACH:
// 正常退出执行的代码
break;
case DLL_PROCESS_DETACH:
// 进程卸载本Dll后执行的代码
break;
}
return TRUE;
}
#include <Windows.h>
#include <iostream> typedef VOID(*PFUNMSG)(LPCWSTR szMsg, LPCWSTR Title); int main(int argc, char *argv[])
{ HMODULE hModule = LoadLibrary("./hook.dll"); if (hModule != NULL)
{
PFUNMSG pMsgBox = (PFUNMSG)GetProcAddress(hModule, "MsgBox");
pMsgBox(L"hello lyshark", L"msgbox");
} system("pause");
return 0;
}

x86 实现远程线程注入: 注入原理是利用了Windows系统中提供的CreateRemoteThread()这个API函数,该函数第四个参数是准备运行的线程,我们将LoadLibrary()函数填入其中,这样就可以执行远程进程中的LoadLibrary()函数,进而将我们自己准备的DLL加载到远程进程空间中执行,DLL在被装载后则会自动执行初始化部分,X86注入代码如下.

#include <windows.h>
#include <stdio.h> // 使用 CreateRemoteThread 实现远线程注入
BOOL CreateRemoteThreadInjectDll(DWORD Pid, char *DllName)
{
HANDLE hProcess = NULL;
SIZE_T dwSize = 0;
LPVOID pDllAddr = NULL;
FARPROC pFuncProcAddr = NULL; // 打开注入进程,获取进程句柄
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, Pid);
if (NULL == hProcess)
{
return FALSE;
}
// 计算欲注入 DLL 文件完整路径的长度
dwSize = sizeof(char)+lstrlen(DllName); // 在目标进程申请一块长度为 nDllLen 大小的内存空间
pDllAddr = VirtualAllocEx(hProcess, NULL, dwSize, MEM_COMMIT, PAGE_READWRITE);
if (NULL == pDllAddr)
{
return FALSE;
}
// 将欲注入 DLL 文件的完整路径写入在目标进程中申请的空间内
if (FALSE == WriteProcessMemory(hProcess, pDllAddr, DllName, dwSize, NULL))
{
return FALSE;
}
// 获得 LoadLibraryA()函数的地址
pFuncProcAddr = GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA");
if (NULL == pFuncProcAddr)
{
return FALSE;
}
// 使用 CreateRemoteThread 创建远线程, 实现 DLL 注入
HANDLE hRemoteThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)pFuncProcAddr, pDllAddr, 0, NULL);
if (NULL == hRemoteThread)
{
return FALSE;
}
// 关闭句柄
CloseHandle(hProcess);
return TRUE;
} int main(int argc, char *argv[])
{
CreateRemoteThreadInjectDll(4668, "./x86.dll");
system("pause");
return 0;
}

x64 实现远程线程注入: 如果想要注入X64程序,则需要在编译时指定为64位编译模式,并且使用LoadLibraryW()来加载动态链接库,我们只需要在上面代码的基础上稍加改进就可以实现64位进程的注入了.

#include <windows.h>
#include <stdio.h> // 使用 CreateRemoteThread 实现远线程注入
BOOL CreateRemoteThreadInjectDll(DWORD Pid, PCWSTR DllName)
{
BOOL ret = FALSE;
HANDLE hProcess, hThread = NULL;
FARPROC pfnThreadRtn = NULL;
PWSTR pwszPara = NULL; // 打开注入进程,获取进程句柄
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, Pid);
if (NULL == hProcess)
{
return FALSE;
} // 计算欲注入 DLL 文件完整路径的长度
size_t iProxyFileLen = wcslen(DllName) * sizeof(WCHAR); // 在目标进程申请一块长度为 nDllLen 大小的内存空间
pwszPara = (PWSTR)VirtualAllocEx(hProcess, NULL, iProxyFileLen, MEM_COMMIT, PAGE_READWRITE);
if (NULL == pwszPara)
{
return FALSE;
} // 将欲注入 DLL 文件的完整路径写入在目标进程中申请的空间内
if (FALSE == WriteProcessMemory(hProcess, pwszPara, (PVOID)DllName, iProxyFileLen, NULL))
{
return FALSE;
} // 获得 LoadLibraryW()函数的地址
pfnThreadRtn = GetProcAddress(GetModuleHandle(TEXT("Kernel32")), "LoadLibraryW");
if (NULL == pfnThreadRtn)
{
return FALSE;
} // 使用 CreateRemoteThread 创建远线程, 实现 DLL 注入
hThread = CreateRemoteThread(hProcess, NULL, 1024, (LPTHREAD_START_ROUTINE)pfnThreadRtn, pwszPara, 0, NULL);
WaitForSingleObject(hThread, INFINITE);
if (NULL != hThread)
{
CloseHandle(hThread);
CloseHandle(hProcess);
VirtualFreeEx(hProcess, pwszPara, 0, MEM_RELEASE);
return TRUE;
}
return FALSE;
} int main(int argc, char *argv[])
{
CreateRemoteThreadInjectDll(8224, L"./x64.dll");
system("pause");
return 0;
}

实现普通消息钩子注入: Windows提供的钩子类型非常多,其中一种类型的钩子非常实用,那就是WH_GETME SSAGE钩子,它可以很方便地将DLL文件注入到所有的基于消息机制的目标程序中,代码非常简单,这里直接给出DLL文件的代码,具体如下:

#include <windows.h>

extern "C" __declspec(dllexport) VOID SetHookOn();
extern "C" __declspec(dllexport) VOID SetHookOff(); HHOOK g_HHook = NULL;
HINSTANCE g_hInst = NULL; VOID DoSomeThing()
{
MessageBoxA(0, "hello lyshark", 0, 0);
} BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved)
{
switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
{
g_hInst = hinstDLL;
DoSomeThing();
break;
}
}
return TRUE;
} LRESULT CALLBACK GetMsgProc(int code,WPARAM wParam,LPARAM lParam)
{
return CallNextHookEx(g_HHook, code, wParam, lParam);
} VOID SetHookOn()
{
g_HHook = SetWindowsHookEx(WH_GETMESSAGE, GetMsgProc, g_hInst, 0);
} VOID SetHookOff()
{
UnhookWindowsHookEx(g_HHook);
}

实现全局消息钩子注入: 该注入的原理是利用系统中的SetWindowHookEx()这个API函数,该函数可以拦截目标进程的消息到指定DLL中的导出函数上,利用这个特性,我们可以将DLL注入到全局进程中,但是在使用SetWindowsHookEx()之前首先需要将HOOK的DLL加载到本身的进程中,以此得到DLL的模块句柄,再使用GetProcAddress()得到DLL中公开的函数地址,最后遍历出待注入进程的线程ID,这样SetWindowHookEx()就可以利用这些参数进行HOOK了.

我们先来编写DLL文件,创建Dll工程hook.cpp然后将SetHook()函数导出,由于该注入方式是全局注入,所以如果我们想要注入到指定进程中,则需要在DllMain()也就是动态链接库开头位置进行判断,如果是我们需要Hook的进程,则加载Dll到指定进程中,如果不是则不执行任何操作,这样一来即可实现指定进程注入.

#include <windows.h>
HHOOK Global_Hook; // 设置全局消息回调函数
LRESULT CALLBACK MyProc(int nCode, WPARAM wParam, LPARAM lParam)
{
return CallNextHookEx(Global_Hook, nCode, wParam, lParam);
}
// 安装全局钩子,此处的hook.dll可以是外部其他的dll
extern "C" __declspec(dllexport) void SetHook()
{
Global_Hook = SetWindowsHookEx(WH_CBT, MyProc, GetModuleHandle(TEXT("hook.dll")), 0);
}
// 卸载全局钩子
extern "C" __declspec(dllexport) void UnHook()
{
if(Global_Hook)
UnhookWindowsHookEx(Global_Hook);
} bool APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
HWND hwnd = FindWindowW(L"valve001",NULL);
DWORD pid;
GetWindowThreadProcessId(hwnd, &pid);
if (GetCurrentProcessId() == pid)
{
MessageBox(hwnd, TEXT("hello lyshark"), 0, 0);
}
return true;
}

调用代码:注意必须将上方编译好的hook.dll与下方工程放到同一个目录下,通过LoadLibrary()函数获取到模块句柄,然后通过GetProcAddress()获取到导出函数地址,并通过函数指针调用,由于全局注入依赖于父进程,所以下面的代码必须一直运行.

#include <windows.h>

int main(int argc, char *argv[])
{
HMODULE hMod = LoadLibrary(TEXT("hook.dll")); typedef void(*pSetHook)(void);
pSetHook SetHook = (pSetHook)GetProcAddress(hMod, "SetHook");
SetHook();
while (1)
{
Sleep(1000);
}
return 0;
}

APC应用层异步注入: APC 是异步过程调用,在Windows下每个线程在可被唤醒时在其APC链中的函数将有机会执行被执行,每一个线程都具有一个APC链,那么只要在可以在APC链中添加一个APC,就可以完成我们所需要的DLL注入的功能.

1.将需要加载的DLL的完整路径写入目标进程空间.

2.获得LoadLibraryA()函数的地址,当然也可以是LoadLibraryW()函数的地址.

3.枚举目标进程中的所有线程,为每个线程添加一个APC函数,这样增加了注入成功的机会.

该注入的原理是利用当线程被唤醒时APC中的注册函数会被执行的机制,并以此去执行我们的DLL加载代码,进而完成DLL注入的目的,通过APC注入的流程步骤大致如下

1.当EXE里某个线程执行到SleepEx()或者WaitForSingleObjectEx()时,系统就会产生一个软中断.

2.当线程再次被唤醒时,此线程会首先执行APC队列中的被注册的函数.

3.利用QueueUserAPC()这个API可以在软中断时向线程的APC队列插入一个函数指针,如果我们插入的是Loadlibrary()执行函数的话,就能达到注入DLL的目的,不论如何目标程序必须有执行SleepEx()或者WaitForSingleObjectEx()否则DLL不会加载.

#include <windows.h>
#include <tlhelp32.h>
#include <stdio.h> // APC注入
BOOL ApcInjectDll(DWORD dwPid, char * szDllName)
{
// 计算欲注入 DLL 文件完整路径的长度
int nDllLen = lstrlen(szDllName) + sizeof(char); // 打开目标进程
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS,FALSE, dwPid);
if (hProcess == NULL)
{
return FALSE;
}
// 在目标进程申请一块长度为 nDllLen 大小的内存空间
PVOID pDllAddr = VirtualAllocEx(hProcess,NULL, nDllLen,MEM_COMMIT,PAGE_READWRITE);
if (pDllAddr == NULL)
{
CloseHandle(hProcess);
return FALSE;
}
DWORD dwWriteNum = 0;
// 将欲注入 DLL 文件的完整路径写入在目标进程中申请的空间内
WriteProcessMemory(hProcess, pDllAddr, szDllName,nDllLen, &dwWriteNum);
CloseHandle(hProcess); THREADENTRY32 te = { 0 };
te.dwSize = sizeof(THREADENTRY32);
//得到线程快照
HANDLE handleSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
if (INVALID_HANDLE_VALUE == handleSnap)
{
CloseHandle(hProcess);
return FALSE;
}
// 获得 LoadLibraryA()函数的地址
FARPROC pFunAddr = GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA");
DWORD dwRet = 0;
//得到第一个线程
if (Thread32First(handleSnap, &te))
{
do
{
//进行进程 ID 对比
if (te.th32OwnerProcessID == dwPid)
{
//得到线程句柄
HANDLE hThread = OpenThread(THREAD_ALL_ACCESS,FALSE,te.th32ThreadID);
if (hThread)
{
//向线程插入 APC
dwRet = QueueUserAPC((PAPCFUNC)pFunAddr,hThread,(ULONG_PTR)pDllAddr);
//关闭句柄
CloseHandle(hThread);
}
}
//循环下一个线程
} while (Thread32Next(handleSnap, &te));
}
CloseHandle(handleSnap);
return TRUE;
} int main(int argc, char *argv[])
{
ApcInjectDll(9608, "c:/x86.dll");
system("pause");
return 0;
}

ZwCreateThreadEx强力注入: 在前面的注入方式中,我们使用了CreateRemoteThread()这个函数来完成线程注入,此方式可以注入普通的进程,但却无法注入到系统进程中,因为系统进程是处在SESSION0高权限级别的会话层.

由于CreateRemoteThread()底层会调用ZwCreateThreadEx()这个未公开的内核函数,所以我们必须手动调用ZwCreateThread()这一内核函数,将第七个参数设置为0即可,ZwCreateThreadEx函数在ntdll.dll中并未声明,所以必须手动使用GetProcAddress函数将其地址导出.

#include <windows.h>
#include <stdio.h> // 使用 ZwCreateThreadEx 实现远线程注入
BOOL ZwCreateThreadExInjectDll(DWORD dwProcessId, char * pDllName)
{
HANDLE hProcess = NULL;
SIZE_T dwSize = 0;
LPVOID pDllAddr = NULL;
FARPROC pFuncProcAddr = NULL;
HANDLE hRemoteThread = NULL;
DWORD dwStatus = 0; // 打开注入进程,获取进程句柄
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
if (NULL == hProcess)
{
return FALSE;
}
// 在注入进程中申请内存
dwSize = sizeof(char)+lstrlen(pDllName);
pDllAddr = ::VirtualAllocEx(hProcess, NULL, dwSize, MEM_COMMIT, PAGE_READWRITE);
if (NULL == pDllAddr)
{
return FALSE;
}
// 向申请的内存中写入数据
if (FALSE == ::WriteProcessMemory(hProcess, pDllAddr, pDllName, dwSize, NULL))
{
return FALSE;
}
// 加载 ntdll.dll
HMODULE hNtdllDll = ::LoadLibrary("ntdll.dll");
if (NULL == hNtdllDll)
{
return FALSE;
}
// 获取LoadLibraryA函数地址
pFuncProcAddr = ::GetProcAddress(::GetModuleHandle("Kernel32.dll"), "LoadLibraryA");
if (NULL == pFuncProcAddr)
{
return FALSE;
}
// 获取ZwCreateThread函数地址
#ifdef _WIN64
typedef DWORD(WINAPI *typedef_ZwCreateThreadEx)(
PHANDLE ThreadHandle,
ACCESS_MASK DesiredAccess,
LPVOID ObjectAttributes,
HANDLE ProcessHandle,
LPTHREAD_START_ROUTINE lpStartAddress,
LPVOID lpParameter,
ULONG CreateThreadFlags,
SIZE_T ZeroBits,
SIZE_T StackSize,
SIZE_T MaximumStackSize,
LPVOID pUnkown);
#else
typedef DWORD(WINAPI *typedef_ZwCreateThreadEx)(
PHANDLE ThreadHandle,
ACCESS_MASK DesiredAccess,
LPVOID ObjectAttributes,
HANDLE ProcessHandle,
LPTHREAD_START_ROUTINE lpStartAddress,
LPVOID lpParameter,
BOOL CreateSuspended,
DWORD dwStackSize,
DWORD dw1,
DWORD dw2,
LPVOID pUnkown);
#endif
typedef_ZwCreateThreadEx ZwCreateThreadEx = (typedef_ZwCreateThreadEx)::GetProcAddress(hNtdllDll, "ZwCreateThreadEx");
if (NULL == ZwCreateThreadEx)
{
return FALSE;
}
// 使用 ZwCreateThreadEx 创建远线程, 实现 DLL 注入
dwStatus = ZwCreateThreadEx(&hRemoteThread, PROCESS_ALL_ACCESS, NULL, hProcess,
(LPTHREAD_START_ROUTINE)pFuncProcAddr, pDllAddr, 0, 0, 0, 0, NULL);
if (NULL == hRemoteThread)
{
return FALSE;
}
// 关闭句柄
::CloseHandle(hProcess);
::FreeLibrary(hNtdllDll);
return TRUE;
} int main(int argc, char *argv[])
{
BOOL bRet = ZwCreateThreadExInjectDll(2940, "hook.dll"); system("pause");
return 0;
}

强制卸载进程中的DLL:

#include <Windows.h>
#include <stdio.h>
#include <TlHelp32.h> BOOL UnLoad_Module(DWORD dwPID, LPCTSTR szDllName)
{
BOOL bMore = FALSE, bFound = FALSE;
HANDLE hSnapshot, hProcess, hThread;
HMODULE hModule = NULL;
MODULEENTRY32 me = { sizeof(me) };
LPTHREAD_START_ROUTINE pThreadProc; hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwPID);
bMore = Module32First(hSnapshot, &me);
for (; bMore; bMore = Module32Next(hSnapshot, &me))
{
if (!_tcsicmp((LPCTSTR)me.szModule, szDllName) || !_tcsicmp((LPCTSTR)me.szExePath, szDllName))
{
bFound = TRUE;
break;
}
}
if (!(hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID)))
return FALSE; hModule = GetModuleHandle(L"kernel32.dll");
pThreadProc = (LPTHREAD_START_ROUTINE)GetProcAddress(hModule, "FreeLibrary");
hThread = CreateRemoteThread(hProcess, NULL, 0, pThreadProc, me.modBaseAddr, 0, NULL);
WaitForSingleObject(hThread, INFINITE);
if (hThread != 0)
{
CloseHandle(hThread);
CloseHandle(hProcess);
CloseHandle(hSnapshot);
return TRUE;
}
return FALSE;
} int main(int argc, char *argv[])
{
UnLoad_Module(2012, "lyshark.dll"); system("pause");
return 0;
}

纯汇编实现远程Dll注入:

.data
szMyDll db "\lyshark.dll",0h ; 要注入的DLL
szDllKernel db "Kernel32.dll",0h
szLoadLibrary db "LoadLibraryA",0h
lpFileName db "Tutorial-i386",0h ; 指定要注入进程
lpDllName dd ?
.data?
szMyDllFull db MAX_PATH dup (?)
lpLoadLibrary dd ?
dwProcessID dd ?
dwThreadID dd ?
hProcess dd ?
.code
main PROC
; 准备工作:获取dll的全路径文件名、获取LoadLibrary函数地址等
invoke GetCurrentDirectory,MAX_PATH,addr szMyDllFull
invoke lstrcat,addr szMyDllFull,addr szMyDll
invoke GetModuleHandle,addr szDllKernel
invoke GetProcAddress,eax,offset szLoadLibrary
mov lpLoadLibrary,eax ; 查找文件管理器窗口并获取进程ID,然后打开进程
invoke FindWindow,NULL,addr lpFileName
invoke GetWindowThreadProcessId,eax,offset dwProcessID
mov dwThreadID,eax
invoke OpenProcess,PROCESS_ALL_ACCESS,FALSE,dwProcessID
mov hProcess,eax ; 在进程中分配空间并将DLL文件名拷贝过去,然后创建一个LoadLibrary线程
invoke VirtualAllocEx,hProcess,NULL,MAX_PATH,MEM_COMMIT,PAGE_READWRITE
mov lpDllName,eax
invoke WriteProcessMemory,hProcess,eax,offset szMyDllFull,MAX_PATH,NULL
invoke CreateRemoteThread,hProcess,NULL,0,lpLoadLibrary,lpDllName,0,NULL
ret
main endp
end main

纯汇编实现远程代码注入:

1.首先使用汇编编写一个代码注入器,其命名为main.asm

.data
lpLoadLibrary dd ?
lpGetProcAddress dd ?
lpGetModuleHandle dd ?
dwProcessID dd ?
dwThreadID dd ?
hProcess dd ?
lpRemoteCode dd ?
.const
ProcHandle db "lyshark.exe",0h
KernelBase db "Kernel32.dll",0h
szLoadLibrary db "LoadLibraryA",0h
szGetProcAddress db "GetProcAddress",0h
szGetModuleHandle db "GetModuleHandleA",0h
.code
include Macro.inc
include ShellCode.asm
main proc
invoke GetModuleHandle,addr KernelBase
mov ebx,eax
invoke GetProcAddress,ebx,offset szLoadLibrary
mov lpLoadLibrary,eax
invoke GetProcAddress,ebx,offset szGetProcAddress
mov lpGetProcAddress,eax
invoke GetProcAddress,ebx,offset szGetModuleHandle
mov lpGetModuleHandle,eax invoke FindWindow,NULL,addr ProcHandle
invoke GetWindowThreadProcessId,eax,offset dwProcessID
mov dwThreadID,eax
invoke OpenProcess,PROCESS_ALL_ACCESS,FALSE,dwProcessID
mov hProcess,eax invoke VirtualAllocEx,hProcess,NULL,2048,MEM_COMMIT,PAGE_EXECUTE_READWRITE
.if eax
mov lpRemoteCode,eax
invoke WriteProcessMemory,hProcess,lpRemoteCode,offset REMOTE_CODE_START,1024,NULL
invoke WriteProcessMemory,hProcess,lpRemoteCode,offset lpLoadLibrary,sizeof dword * 3,NULL
mov eax,lpRemoteCode
add eax,offset _RemoteThread - offset REMOTE_CODE_START
invoke CreateRemoteThread,hProcess,NULL,0,eax,0,0,NULL
invoke CloseHandle,eax
.endif
invoke CloseHandle,hProcess
invoke ExitProcess,NULL
ret
main endp
end main

为了后期编程方便,编写一个反转宏Macro.inc用来翻转参数,使用定义_invoke调用更方便

; --------------------------------------------
; 翻转参数字节序
reverseArgs macro arglist:VARARG
LOCAL txt,count
txt TEXTEQU <>
count=0
for i,<arglist>
count = count+1
txt TEXTEQU @CatStr(i,<!,>,<%txt>)
endm
if count GT 0
txt SUBSTR txt,1,@SizeStr(%txt)-1
endif
exitm txt
endm
; --------------------------------------------
; 创建类似于INVOKE的宏代码
_invoke macro _Proc,args:VARARG
LOCAL count
count = 0
% for i,< reverseArgs( args ) >
count = count+1
push i
endm
call dword ptr _Proc
endm

最后编写注入代码,此处命名为shellcode.asm该代码包括了子定位功能.

REMOTE_CODE_START equ this byte
_lpLoadLibrary dd ?
_lpGetProcAddress dd ?
_lpGetModuleHandle dd ? ; --------------------------------------------
; 存放静态资源,比如常量,字符串等.
_hInstance dd ?
_szShowTitle db "hello lyshark",0h ; --------------------------------------------
; 存放获取到的指针
_lpDllUser dd ?
_lpMessageBox dd ?
; --------------------------------------------
; 放入导入函数的字符串
_szDllUser db "user32.dll",0h
_szMessageBox db "MessageBoxA",0h,0
; --------------------------------------------
_RemoteThread proc uses ebx esi edi
LOCAL @hModule
; --------------------------------------------
; 计算指令的偏移地址,用ebx作为基址指针
call @F
@@:
pop ebx
sub ebx,offset @B
; --------------------------------------------
_invoke [ebx + _lpGetModuleHandle],NULL ; 取当前模块句柄
mov [ebx + _hInstance],eax
lea eax,[ebx + offset _szDllUser]
_invoke [ebx + _lpGetModuleHandle],eax ; 取user32.dll模块句柄
mov @hModule,eax
; --------------------------------------------
; 循环获取每个导入函数的地址,并放入指针变量保存
lea esi,[ebx + offset _szMessageBox] ; 循环获取,从该函数起始地址处
lea edi,[ebx + offset _lpMessageBox]
.while TRUE
_invoke [ebx + _lpGetProcAddress],@hModule,esi
mov [edi],eax ; 获取到函数地址后,放入导入函数字符串中
add edi,4 ; 每次递增4字节,指向下一个函数,遇到0则停止
@@:
lodsb
or al,al
jnz @B
.break .if !byte ptr [esi]
.endw
; --------------------------------------------
;lea esi,[ebx+ offset _szMessageBox] ; 取msgbox模块地址
;_invoke [ebx+_lpGetProcAddress],@hModule,esi ; 获取地址
;mov [ebx+_lpMessageBox],eax ; 存入变量中
lea esi,[ebx + offset _szShowTitle] ; 获取弹窗资源
_invoke [ebx + _lpMessageBox],0,esi,eax,0 ; 调用信息框
ret
_RemoteThread endp

C/C++ 实现常用的线程注入的更多相关文章

  1. windows-CODE注入(远程线程注入)

    远程线程注入(先简单说,下面会详细说)今天整理下代码注入(远程线程注入),所谓代码注入,可以简单的理解为是在指定内进程里申请一块内存,然后把我们自己的执行代码和一些变量拷贝进去(通常是以启线程的方式) ...

  2. 远程线程注入方法CreateRemoteThread

    最近在整理学习Windows注入方面的知识,这个远程注入前面早写过,现在看看人家博客的理解整理,整理, 需要源码的可以到我的github上下载. 链接是  https://github.com/Ars ...

  3. 安全之路 —— 借助DLL进行远程线程注入实现穿墙与隐藏进程

    简介        大多数后门或病毒要想初步实现隐藏进程,即不被像任务管理器这样典型的RING3级进程管理器找到过于明显的不明进程,其中比较著名的方法就是通过远程线程注入的方法注入将恶意进程的DLL文 ...

  4. 安全之路 —— 无DLL文件实现远程线程注入

    简介         在之前的章节中,笔者曾介绍过有关于远程线程注入的知识,将后门.dll文件注入explorer.exe中实现绕过防火墙反弹后门.但一个.exe文件总要在注入时捎上一个.dll文件着 ...

  5. 详细解读:远程线程注入DLL到PC版微信

    一.远程线程注入的原理 1.其基础是在 Windows 系统中,每个 .exe 文件在双击打开时都会加载 kernel32.dll 这个系统模块,该模块中有一个 LoadLibrary() 函数,可以 ...

  6. Dll注入技术之远程线程注入

    DLL注入技术之远线程注入 DLL注入技术指的是将一个DLL文件强行加载到EXE文件中,并成为EXE文件中的一部分,这样做的目的在于方便我们通过这个DLL读写EXE文件内存数据,(例如 HOOK EX ...

  7. 远程线程注入dll,突破session 0

    前言 之前已经提到过,远线程注入和内存写入隐藏模块,今天介绍突破session 0的dll注入 其实今天写这个的主要原因就是看到倾旋大佬有篇文章提到:有些反病毒引擎限制从lsass中dump出缓存,可 ...

  8. mfc HackerTools远程线程注入

    在一个进程中,调用CreateThread或CreateRemoteThreadEx函数,在另一个进程内创建一个线程(因为不在同一个进程中,所以叫做远程线程).创建的线程一般为Windows API函 ...

  9. 远程线程注入DLL突破session 0 隔离

    远程线程注入DLL突破session 0 隔离 0x00 前言 补充上篇的远程线程注入,突破系统SESSION 0 隔离,向系统服务进程中注入DLL. 0x01 介绍 通过CreateRemoteTh ...

  10. 远程线程注入DLL

    远程线程注入 0x00 前言 远程线程注入是一种经典的DLL注入技术.其实就是指一个新进程中另一个进程中创建线程的技术. 0x01 介绍 1.远程线程注入原理 画了一个图大致理解了下远程线程注入dll ...

随机推荐

  1. Sunshine + Moonlight 纯软件实现全平台设备作 Linux 副屏

    目录 初识 Moonlight 部署 Sunshine 服务端与 Moonlight 客户端 创建虚拟显示屏 写一个创建屏幕的脚本(可选) 将副屏进行串流 已知问题 最近,我想要通过视频学习一些技术知 ...

  2. springboot 整合 ehcahe后,实现缓存数据 应用关闭时序列化(磁盘持久化),重启再加载

    ehcache使用很长时间了,但是却没有用到缓存数据序列化(C#中是这么个说法)与再加载.这次因为业务中需要对缓存数据进行临时存储并再加载使用,实现该功能的方式多种多样.既然ehcache有磁盘保存机 ...

  3. #2612:Find a way(BFS搜索+多终点)

    第一次解决双向BFS问题,拆分两个出发点分BFS搜索 #include<cstdio> #include<cstring> #include<queue> usin ...

  4. Codeforces Round #739 (Div. 3) 个人题解(A~F2)

    比赛链接:Here 1560A. Dislike of Threes Description 找出第 $k$ 大的不可被 $3$ 整除以及非 $3$ 结尾的整数 直接枚举出前 1000 个符合条件的数 ...

  5. AtCoder Beginner Contest 172 (C题前缀和 + 二分,D题筛因子,E题容斥定理)

    AB水题, C - Tsundoku 题目描述 有两摞书,一摞有 $n$ 本,从上至下每本需阅读 $a_i$ 分钟,一摞有 $m$ 本,从上至下每本需阅读 $b_i$ 分钟,问最多能在 $k$ 分钟内 ...

  6. 【数据库】E-R图向关系模型转换的规则

    E-R图向关系模型转换的规则: (1) 一个实体型转换为一个关系模式,实体的属性就是关系的属性,实体的码(关键字)就是关系的码. (2) 一个 1:1 联系可以转换为一个独立的关系模式,也可以与任意一 ...

  7. Codeforces Round #565 (Div. 3) (重现赛个人题解)

    1176A. Divide it! 题目链接:http://codeforces.com/problemset/problem/1176/A 题意: 给定一个数字 \(n\) 和三种操作 如果 n 能 ...

  8. vue用qrcodejs2生成二维码,解决多个二维码追加的问题

    vue使用qrcodejs2生成二维码 1.安装qrcodejs2 npm install qrcodejs2 2.代码 //导入组件 import QRCode from 'qrcodejs2' / ...

  9. loadrunner12的安装教程

    一.LR12安装包: 链接:https://pan.baidu.com/s/1UU304e-nP7qAL-fV8T39YQ 密码:jpln 二.LR12安装: 1.下载完成后点击解压

  10. 到底什么样的 Java 项目用 Solon 好???

    什么样的 Java 项目用 Solon 好 就像华为讲的,不要因为爱国而特意买华为手机.Solon 也是,有需要就用不需要就跳过(按正常的需求选择): 信创需要国产化,应该用 Solon 或者 Sol ...