原理介绍
原理同上一篇一样,这里使用汇编语言进行实现代码注入的功能
使用汇编来编写ThreadProc函数,然后直接把汇编指令写入目标内容进行调用,比上一节少了计算函数大小的步骤
本节进行讲解汇编的写法,和注入代码的写法
汇编实现
使用x32dbg打开一个测试用的exe,用来编写汇编代码:
我这里用到还是之前的hello world程序
拉到最上面,右键,设置新的运行点,把eip设置过来(这种方式不改变栈和寄存器的内容)
然后就可以开始编写汇编代码了:
这里很妙的一个地方就是,对call的巧用:call指令其实是push+jmp的组合,将下一条命令push入栈,而这里call下一行是字符串,然后jmp到指定地方,就是下一个参数的位置,通过call巧妙的在代码段中将字符串入栈作为参数
然后其他的很简单,没什么好说的了,都在注释里
右键选中修改的区域,然后二进制,复制,得到我们写的汇编:
55 8B EC 8B 75 08 68 6C 6C 00 00 68 33 32 2E 64
68 75 73 65 72 54 FF 16 68 6F 78 41 00 68 61 67
65 42 68 4D 65 73 73 54 50 FF 56 04 6A 00 E8 06
00 00 00 68 65 6C 6C 6F 00 E8 06 00 00 00 45 52
52 4F 52 00 6A 00 FF D0 33 C0 8B E5 5D C3
稍作修改得到如下样子:加上0x和逗号
准备工作就完成了,就可以开始写代码了
代码实现
#include<stdio.h>
#include<windows.h>
//Thread Parameter
typedef struct _THREAD_PARAM {
FARPROC pFunc[2];
}THREAD_PARAM, * PTHREAD_PARAM;
BYTE g_InjectionCode[] = {
0x55,0x8B,0xEC,0x8B,0x75,0x08,0x68,0x6C,0x6C,0x00,0x00,0x68,0x33,0x32,0x2E,0x64,
0x68,0x75,0x73,0x65,0x72,0x54,0xFF,0x16,0x68,0x6F,0x78,0x41,0x00,0x68,0x61,0x67,
0x65,0x42,0x68,0x4D,0x65,0x73,0x73,0x54,0x50,0xFF,0x56,0x04,0x6A,0x00,0xE8,0x06,
0x00,0x00,0x00,0x68,0x65,0x6C,0x6C,0x6F,0x00,0xE8,0x06,0x00,0x00,0x00,0x45,0x52,
0x52,0x4F,0x52,0x00,0x6A,0x00,0xFF,0xD0,0x33,0xC0,0x8B,0xE5,0x5D,0xC3
};
BOOL InjectCode(DWORD dwPid)
{
HMODULE hMod = GetModuleHandleA("kernel32.dll");
THREAD_PARAM param = { 0, };
param.pFunc[0] = GetProcAddress(hMod, "LoadLibraryA");
param.pFunc[1] = GetProcAddress(hMod, "GetProcAddress");
//Open Process
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid);
//Allocation for THREAD_PARAM
DWORD dwWrittenSize = 0;
DWORD dwSize = sizeof(THREAD_PARAM);
LPVOID pRemoteBuf[2] = { 0, };
pRemoteBuf[0] = VirtualAllocEx(hProcess, NULL, dwSize, MEM_COMMIT, PAGE_READWRITE);
WriteProcessMemory(hProcess, pRemoteBuf[0], ¶m, dwSize, &dwWrittenSize);
//Allocation for ThreadFunc
dwSize = sizeof(g_InjectionCode);
pRemoteBuf[1] = VirtualAllocEx(hProcess, NULL, dwSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
WriteProcessMemory(hProcess, pRemoteBuf[1], (LPVOID)&g_InjectionCode, dwSize, &dwWrittenSize);
//code injection
HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)pRemoteBuf[1], pRemoteBuf[0], 0, NULL);
//WaitForSingleObject(hThread, INFINITE);
CloseHandle(hThread);
CloseHandle(hProcess);
return TRUE;
}
int main(int argc, char* argv[]) {
//DWORD dwPid = (DWORD)atol(argv[1]);
DWORD dwPid = 1036;
InjectCode(dwPid);
}
效果演示
为啥老用这个CM来做演示呢?主要是懒,这个应用就在桌面上,点开即用哈哈哈哈
当然,对其他应用也有用,比如刚好已经打开了的TIM: