天魔降临
路旁的落叶
来自: 金钱:423 发帖数: 59 注册日期: 2005-11-03
| 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
LE***E
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 最后编辑
向版主反映这个帖子 | IP: 已记录
|
|