0x04.注入方法二 -- 设置线程上下背景文
设置线程上下背景文的主要目的是让目标进程的某一线程转去执行我们的代码,然后再回来做他该做的事,而我们的代码,就是一串由汇编硬编码组成的ShellCode。
这串ShellCode做了三件事:1.传入Dll完整路径参数;2.呼叫LoadLibrary函数地址;3.返回原先的Eip或Rip。
这里我选用的呼叫指令是ff 15 和 ff 25,在32位下为跳转到15(25)指令后面字节码对应地址里面存放的地址,在64位下15(25)指令后面四字节存放的是偏移,该跳转为跳转到换算出来的地址里面存放的地址,这里我把偏移写成0,以便于计算。
#ifdef _WIN64
// 测试 64 位 dll被注,Bug已修复
/*
0:019> u 0x000002b5d5f80000
000002b5`d5f80000 4883ec28 sub rsp,28h
000002b5`d5f80004 488d0d20000000 lea rcx,[000002b5`d5f8002b]
000002b5`d5f8000b ff1512000000 call qword ptr [000002b5`d5f80023]
000002b5`d5f80011 4883c428 add rsp,28h
000002b5`d5f80015 ff2500000000 jmp qword ptr [000002b5`d5f8001b]
*/
UINT8 ShellCode[0x100] = {
0x48,0x83,0xEC,0x28, // sub rsp ,28h
0x48,0x8D,0x0d, // [+4] lea rcx,
0x00,0x00,0x00,0x00, // [+7] DllNameOffset = [+43] - [+4] - 7
// call 跳偏移,到地址,解*号
0xff,0x15, // [+11]
0x00,0x00,0x00,0x00, // [+13]
0x48,0x83,0xc4,0x28, // [+17] add rsp,28h
// jmp 跳偏移,到地址,解*号
0xff,0x25, // [+21]
0x00,0x00,0x00,0x00, // [+23] LoadLibraryAddressOffset
// 存放原先的 rip
0x00,0x00,0x00,0x00, // [+27]
0x00,0x00,0x00,0x00, // [+31]
// 跳板 loadlibrary地址
0x00,0x00,0x00,0x00, // [+35]
0x00,0x00,0x00,0x00, // [+39]
// 存放dll完整路径
// 0x00,0x00,0x00,0x00, // [+43]
// 0x00,0x00,0x00,0x00 // [+47]
// ......
};
#else
// 测试 32 位 配合新写的Dll可重复注入
/*
0:005> u 0x00ca0000
00000000`00ca0000 60 pusha
00000000`00ca0001 9c pushfq
00000000`00ca0002 681d00ca00 push 0CA001Dh
00000000`00ca0007 ff151900ca00 call qword ptr [00000000`01940026]
00000000`00ca000d 9d popfq
00000000`00ca000e 61 popa
00000000`00ca000f ff251500ca00 jmp qword ptr [00000000`0194002a]
*/
UINT8 ShellCode[0x100] = {
0x60, // [+0] pusha
0x9c, // [+1] pushf
0x68, // [+2] push
0x00,0x00,0x00,0x00, // [+3] ShellCode +
0xff,0x15, // [+7] call
0x00,0x00,0x00,0x00, // [+9] LoadLibrary Addr Addr
0x9d, // [+13] popf
0x61, // [+14] popa
0xff,0x25, // [+15] jmp
0x00,0x00,0x00,0x00, // [+17] jmp eip
// eip 地址
0x00,0x00,0x00,0x00, // [+21]
// LoadLibrary 地址
0x00,0x00,0x00,0x00, // [+25]
// DllFullPath
0x00,0x00,0x00,0x00 // [+29]
};
#endif
整个注入过程由这些步骤组成:在目标进程申请内存(可执行内存) ---> 填充ShellCode需要的地址码 ---> 将ShellCode写入申请的内存 ---> SuspendThread(挂起线程)--->GetThreadContext(获得线程上下背景文)---> 修改Context的Eip或Rip为ShellCode首地址 ---> SetThreadContext(设置刚修改过的Context)---> ResumeThread(恢复线程执行)。









