No.3 代码注入(这不是水帖,因为J.Y MM在这,我才在这发的)3 4.3一些关于构建新的PE文件的说明
用一下片断来排列虚拟地址和每个节区的虚拟大小
Code:
image_section_header[i]->VirtualAddress= PEAlign(image_section_header[i]->VirtualAddress, image_nt_headers->OptionalHeader.SectionAlignment);
image_section_header[i]->Misc.VirtualSize= PEAlign(image_section_header[i]->Misc.VirtualSize, image_nt_headers->OptionalHeader.SectionAlignment);
|
Align the PointerToRawData and the SizeOfRawData of each section by FileAlignment
Code:
image_section_header[i]->PointerToRawData = PEAlign(image_section_header[i]->PointerToRawData, image_nt_headers->OptionalHeader.FileAlignment);
image_section_header[i]->SizeOfRawData = PEAlign(image_section_header[i]->SizeOfRawData, image_nt_headers->OptionalHeader.FileAlignment);
|
Correct the SizeofImage by the virtual size and the virtual address of the last section
Code:
image_nt_headers->OptionalHeader.SizeOfImage = image_section_header[LastSection]->VirtualAddress + image_section_header[LastSection]->Misc.VirtualSize;
|
Set the Bound Import Directory header to zero, as this directory is not very important to execute a PE file:
Code:
image_nt_headers-> OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT]. VirtualAddress = 0; image_nt_headers-> OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].Size = 0;
|
4.4一些关于连接这个VC程序的解释
Set Linker->General->Enable Incremental Linking to No (/INCREMENTAL:NO).
你能了解增加连接和不增加连接之间的不同
为了获得DynLoader(), 的虚拟地址,再增加LINK中我们获得JMP pemaker.DynLoader 的虚拟地址。但是不使
用LINK时用以下代码获得地址
Code:
DWORD dwVA= (DWORD) DynLoader;
|
This setting is more critical in the incremental link when you try to find the beginning and ending of the Loader,
DynLoader(), by CPECryptor::ReturnToBytePtr():(抱歉,这句话偶不知道如何才能翻译通顺 )
Code:
void* CPECryptor::ReturnToBytePtr(void* FuncName, DWORD findstr) { void* tmpd; __asm { mov eax, FuncName jmp df hjg: inc eax df: mov ebx, [eax] cmp ebx, findstr jnz hjg mov tmpd, eax } return tmpd; }
|
5.保存重要的数据和延伸原入口点
现在,我们已经保存了原入口点,并映射了基地址以便于到达虚拟地址入口点。在DynLoader()结尾处我已
经保存一个空白区来储存这些重要的数据。DynLoader Step 2.
PE Maker - Step 2
Download source files - 58.3 Kb
Code:
DynLoaderStep2>DynLoader Step 2
__stdcall void DynLoader() { _asm { //---------------------------------- DWORD_TYPE(DYN_LOADER_START_MAGIC) //---------------------------------- Main_0: PUSHAD // get base ebp CALL Main_1 Main_1: POP EBP SUB EBP,OFFSET Main_1 MOV EAX,DWORD PTR [EBP+_RO_dwImageBase] ADD EAX,DWORD PTR [EBP+_RO_dwOrgEntryPoint] PUSH EAX RETN // >> JMP to Original OEP //---------------------------------- DWORD_TYPE(DYN_LOADER_START_DATA1) //----------------------------------<FONT color=red> _RO_dwImageBase: DWORD_TYPE(0xCCCCCCCC) _RO_dwOrgEntryPoint: DWORD_TYPE(0xCCCCCCCC)</FONT> //---------------------------------- DWORD_TYPE(DYN_LOADER_END_MAGIC) //---------------------------------- } }
|
5.1恢复开始时寄存器间的关系
恢复他们间的关系是重要的,但在DynLoader Step 2的源代码中我们还没有做这件事。我们可以修改
DynLoader() 函数来重建开始的关系
Code:
__stdcall void DynLoader() { _asm { //---------------------------------- DWORD_TYPE(DYN_LOADER_START_MAGIC) //---------------------------------- Main_0: <FONT color=red>PUSHAD// Save the registers context in stack</FONT> CALL Main_1 Main_1: POP EBP// Get Base EBP SUB EBP,OFFSET Main_1 MOV EAX,DWORD PTR [EBP+_RO_dwImageBase] ADD EAX,DWORD PTR [EBP+_RO_dwOrgEntryPoint] MOV DWORD PTR [ESP+1Ch],EAX // pStack.Eax <- EAX <FONT color=red>POPAD // Restore the first registers context from stack</FONT> PUSH EAX XOR EAX, EAX RETN // >> JMP to Original OEP //---------------------------------- DWORD_TYPE(DYN_LOADER_START_DATA1) //---------------------------------- _RO_dwImageBase: DWORD_TYPE(0xCCCCCCCC) _RO_dwOrgEntryPoint: DWORD_TYPE(0xCCCCCCCC) //---------------------------------- DWORD_TYPE(DYN_LOADER_END_MAGIC) //---------------------------------- } }
|
5.2恢复最初的堆栈
我们能利用设置在堆栈开始处的值加0x34到原入口点,来恢复原始的堆栈,但这不是很重要。然而在下
面的代码中我用了一个简单的技巧来到达OEP以便于修改堆栈,你能利用OD来跟踪执行过程。
Code:
__stdcall void DynLoader() { _asm { //---------------------------------- DWORD_TYPE(DYN_LOADER_START_MAGIC) //---------------------------------- Main_0: PUSHAD // Save the registers context in stack CALL Main_1 Main_1: POP EBP SUB EBP,OFFSET Main_1 MOV EAX,DWORD PTR [EBP+_RO_dwImageBase] ADD EAX,DWORD PTR [EBP+_RO_dwOrgEntryPoint] MOV DWORD PTR [ESP+54h],EAX // pStack.Eip <- EAX POPAD // Restore the first registers context from stack CALL _OEP_Jump DWORD_TYPE(0xCCCCCCCC) _OEP_Jump: PUSH EBP MOV EBP,ESP MOV EAX,DWORD PTR [ESP+3Ch] // EAX <- pStack.Eip MOV DWORD PTR [ESP+4h],EAX // _OEP_Jump RETURN pointer <- EAX XOR EAX,EAX LEAVE RETN //---------------------------------- DWORD_TYPE(DYN_LOADER_START_DATA1) //---------------------------------- _RO_dwImageBase: DWORD_TYPE(0xCCCCCCCC) _RO_dwOrgEntryPoint: DWORD_TYPE(0xCCCCCCCC) //---------------------------------- DWORD_TYPE(DYN_LOADER_END_MAGIC) //---------------------------------- } }
|
5.3Approach OEP by Structured Exception Handling(借助于构造异常处理来接近OEP)
当程序执行了错误的代码就会抛出一个异常,在这种条件下,程序迅速跳转到一个叫做异常处理的功能
中。
下面的文件包含了异常处理的调用,异常的抛出,以及其功能。
Code:
#include "stdafx.h" #include "windows.h"
void RAISE_AN_EXCEPTION() { _asm { INT 3 INT 3 INT 3 INT 3 } }
int _tmain(int argc, _TCHAR* argv[]) { __try { __try{ printf("1: Raise an Exception/n"); RAISE_AN_EXCEPTION(); } __finally { printf("2: In Finally/n"); } } __except( printf("3: In Filter/n"), EXCEPTION_EXECUTE_HANDLER ) { printf("4: In Exception Handler/n"); } return 0; }
|
;Code:
main() 00401000: PUSH EBP 00401001: MOV EBP,ESP 00401003: PUSH -1 00401005: PUSH 00407160 ; __try { ; the structured exception handler (SEH) installation 0040100A: PUSH _except_handler3 0040100F: MOV EAX,DWORD PTR FS:[0] 00401015: PUSH EAX 00401016: MOV DWORD PTR FS:[0],ESP 0040101D: SUB ESP,8 00401020: PUSH EBX 00401021: PUSH ESI 00401022: PUSH EDI 00401023: MOV DWORD PTR SS:[EBP-18],ESP ; __try { 00401026: XOR ESI,ESI 00401028: MOV DWORD PTR SS:[EBP-4],ESI 0040102B: MOV DWORD PTR SS:[EBP-4],1 00401032: PUSH OFFSET "1: Raise an Exception" 00401037: CALL printf 0040103C: ADD ESP,4 ; the raise a exception, INT 3 exception ; RAISE_AN_EXCEPTION() 0040103F: INT3 00401040: INT3 00401041: INT3 00401042: INT3 ; } __finally { 00401043: MOV DWORD PTR SS:[EBP-4],ESI 00401046: CALL 0040104D 0040104B: JMP 00401080 0040104D: PUSH OFFSET "2: In Finally" 00401052: CALL printf 00401057: ADD ESP,4 0040105A: RETN <FONT color=black>; } <FONT color=black>; } <FONT color=black>; __except( 0040105B: JMP 00401080 0040105D: PUSH OFFSET "3: In Filter" 00401062: CALL printf 00401067: ADD ESP,4 0040106A: MOV EAX,1 ; EXCEPTION_EXECUTE_HANDLER = 1 0040106F: RETN ; , EXCEPTION_EXECUTE_HANDLER ) ; } ; the exception handler funtion 00401070: MOV ESP,DWORD PTR SS:[EBP-18] 00401073: PUSH OFFSET "4: In Exception Handler" 00401078: CALL printf 0040107D: ADD ESP,4 ; } 00401080: MOV DWORD PTR SS:[EBP-4],-1 0040108C: XOR EAX,EAX ; restore previous SEH 0040108E: MOV ECX,DWORD PTR SS:[EBP-10] 00401091: MOV DWORD PTR FS:[0],ECX 00401098: POP EDI 00401099: POP ESI 0040109A: POP EBX 0040109B: MOV ESP,EBP 0040109D: POP EBP 0040109E: RETN
| . . . . . . . . . . . . . . . . . . 偶也玩起了BLOG,www.code47.blogcn.com 由 天魔降临 于 2006-03-05 09:33 PM 最后编辑
|