我也贴一个,这是看雪以前的精华里包含的一个程序,然后我不是按照Code_inside方法修改的
******************************************************************************
Target SantMat's ReverseMe 3
******************************************************************************
Author: SantMat
Protection: None
URL: http://www.immortaldescendants.org/users/santmat/reversemes/reme3.zip
Needs: Hiew,WinHex,Some PE knowledge,Most important is Our Brain
我们的目标是SantMat的ReverseMe3,你可以按以上URL下载,也可以在我的主页
下载,我们要使它弹出一个MessageBox.有关PE的知识你可以参看Iczelion的文章
!都是e文的,当然你也可以到看学那里下载,里面有翻译好了的中文! 好了我们现在
假设你已经了解了相关的PE知识.
Let Begin.......
我们将在offset 9FF处增加长度,我们从offset 220处开始到offset 3FF选中
它,然后复制到文件尾部,以便我们以后修改!增加了offset A00到offset BDF的
长度!
好了现在我们开始修改PE头的内容:一个是Section部分,我们知道从PE头开始
偏移0x06是Section的数目,至于PE头的起始是根据IMAGE_DOS_HEADER部分开始来
推出来的!从文件头开始偏移0x3C是e_lfanew字段,它指向PE头"PE",0,0,简单的
方法我们可以直接用UE看到右边的ASCII中的PE,那就是PE的开始的地方,我们偏
移0x06修改Section:
000000B0 50 45 00 00 4C 01 03 00 1A 9A DB 39 00 00 00 00 PE..L....氎9....
Change To: @||@
/
000000B0 50 45 00 00 4C 01 04 00 1A 9A DB 39 00 00 00 00 PE..L....氎9....
我们改变了Section的数目,现在我们来填充进去,看看Section Table的结构:
IMAGE_SECTION_HEADER STRUCT
Name1 db IMAGE_SIZEOF_SHORT_NAME dup(?) ;块名,8个字节
union Misc
PhysicalAddress dd ?
VirtualSize dd ?
ends
VirtualAddress dd ? ;该块的RVA
SizeOfRawData dd ? ;在文件对齐后的尺寸
PointerToRawData dd ? ;在文件中的偏移
PointerToRelocations dd ? ;无用
PointerToLinenumbers dd ? ;无用
NumberOfRelocations dw ? ;无用
NumberOfLinenumbers dw ? ;无用
Characteristics dd ? ;块属性
IMAGE_SECTION_HEADER ENDS
我们可以知道块的大小是40个字节即0x28,同时第一个块的起始位置是PE的offset
加上0xF8,这里我们PE头的开始处是0xB0,我们加上0xF8,即0xB0+0xF8=0x1A8,我们查看
0x1A8处,看到了吧,是块名".text",同理你可以在加上0x28,我们就到了第二个块的位置
0x1A8+0x28=0x1D0,看到了第二个块名称了吧是".rdata"同理我们可以在接下的0x28处
得到第三个块的信息,在这个程序里面是0x1D0+0x28=0x1F8,即".data",接下来是下一个
0x28处是我们的第四个Section的信息,所以我们要手动添加内容(Need PE Knowledge):
+0 8byte Name1 ;块名dengkeng
+8 dword VirtualSize ;100,That's enough
+C dword VirtualAddress ;0x4000
10 dword SizeOfRawData ;0x200
14 dword PointerToRawData ;我们的从0xA00开始
18 dword PointerToRelocations ;一般为0x00000000
1C dword PointerToLinenumbers ;一般为0x00000000
20 word NumberOfRelocations ;一般为0x0000
22 word NumberOfLinenumbers ;一般为0x0000
24 dword Characteristics -----> ours is write read execute and code.so it's E0000020
需要说明的地方是PointerToRawData,我们从0xA00开始,因为第三个Section的PointerToRawData
是从0x800开始的,并且SizeOfRawData是0x200,所以我们开始的位置是0x800+0x200=0xA00.
下面我们开始修改:0x1F8+0x28=0x220,是我们Section开始的地方
00000220 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000230 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000240 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
Change To:
00000220 64 65 6E 67 6B 65 6E 67 00 01 00 00 00 40 00 00 dengkeng.....@..
00000230 00 02 00 00 00 0A 00 00 00 00 00 00 00 00 00 00 ................
00000240 00 00 00 00 20 00 00 E0 00 00 00 00 00 00 00 00 .... ..?.......
接下来我们要做的是增加一个API,MessageBox,它在User32.dll中,好了,在这之前我们
有必要了解一下,Import Table(输入表),我们可以在据PE头0x80处找到它,即0xB0+0x80=0x130
我们看到了如下内容:
00000130 08 20 00 00 28 00 00 00 00 00 00 00 00 00 00 00 . ..(...........
我们看到在0x130处的内容是0x00002008,是数据的起始地址,0x00000028是它的大小,我们得到
磁盘上的offset,2080在".rdata"Section中,它的Raw Offset是600,所以我们查看608处的内容:
Begin=>||
/
00000600 38 20 00 00 00 00 00 00 30 20 00 00 00 00 00 00 8 ......0 ......
00000610 00 00 00 00 46 20 00 00 00 20 00 00 ($)00 00 00 00 ....F ... ......
00000620 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000630 38 20 00 00 00 00 00 00 75 00 45 78 69 74 50 72 8 ......u.ExitPr
00000640 6F 63 65 73 73 00 4B 45 52 4E 45 4C 33 32 2E 64 ocess.KERNEL32.d
00000650 6C 6C 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ll..............
00000660 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000670 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000680 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
在offset 0x608处,Import Table的内容,我们看一下Import Table结构:
IMAGE_IMPORT_DESCRIPTOR STRUCT
union
Characteristics dd ?
OriginalFirstThunk dd ? ;IMAGE_THUNK_DATA数组的RVA,每个指针指向IMAGE_IMPORT_BY_NAME结构
ends
TimeDateStamp dd ? ;32位时间标志,忽略
ForwarderChain dd ? ;忽略
Name1 dd ? ;指向Dll名字
FirstThunk dd ? ;IMAGE_THUNK_DATA数组的RVA
IMAGE_IMPORT_DESCRIPTOR ENDS
这里是:
+0 OriginalFirstThunk ;0x00002038
+4 TimeDateStamp ;0x00000000
+8 ForwarderChain ;0x00000000
+C Name1 ;0x00002046
+10 FirstThunk ;0x00002000
FirstThunk,OriginalFirstThunk都指向两个相同的数组IMAGE_THUNK_DATA,这些数组称为
输入名称表(Import Name Table,INT)和地址输入表(Import Address Table,IAT).两者的区别
是INT不可改写,IAT则是由PE装载器重写的.(具体操作请查有关资料)
IMAGE_IMPORT_DESCRIPTOR结构是以5个dd全0的结构结束,在上面的'$'处就是结束的开始地方,
接下来是5个全0的dd.
我们可以看到这OriginalFirstThunk,Name1,FirstThunk中的内容:
0x00002038 <======>offset 0x638 ;指向IMAGE_IMPORT_BY_NAME
0x00002046 <======>offset 0x646 ;指向KERNEL32.dll字符串
0x00002000 <======>offset 0x600 ;内容为0x00002038(offset 0x638)
IMAGE_IMPORT_BY_NAME STRUCT
Hint dw ? ;是本函数在所其驻留DLL的输出表中的序号
Name1 db ? ;函数名,以NULL结尾
IMAGE_IMPORT_BY_NAME ENDS
OriginalFirstThunk指向IMAGE_IMPORT_BY_NAME,0x0075则是Hint,后面的则是函数名.FirstThunk
中的内容也是指向0x638,即都是指向同一处.
接下来我们要在我们新的Section中增加内容:
offset 00000A00 00000000
offset 00000A04 00000000
offset 00000A08 00000000
offset 00000A0C 00002046
offset 00000A10 00002000
接下来是另一个IID:
offset 00000A14 00000000
offset 00000A18 00000000
offset 00000A1C 00000000
offset 00000A20 00004044 ;这个地方是根据后面推出来的,先不急
offset 00000A24 0000403C ;这个地方是根据后面推出来的,先不急
我们开始添加:
00000A00 00 00 00 00 00 00 00 00 00 00 00 00 46 20 00 00 ............F ..
00000A10 00 20 00 00 00 00 00 00 00 00 00 00 00 00 00 00 . ..............
00000A20 44 40 00 00 3C 40 00 00 00 00 00 00 00 00 00 00 D@..<@..........
00000A30 00 00 00 00 00 00 00 00 00 00 00 00 50 40 00 00 ............P@..
00000A40 00 00 00 00 75 73 65 72 33 32 2E 64 6C 6C 00 00 ....user32.dll..
00000A50 00 00 4D 65 73 73 61 67 65 42 6F 78 41 00 00 00 ..MessageBoxA...
00000A60 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000A70 43 72 61 63 6B 00 00 00 00 00 00 00 00 00 00 00 Crack...........
00000A80 4D 6F 64 69 66 79 20 74 68 65 20 52 65 76 65 72 Modify the Rever
00000A90 73 65 6D 65 20 42 79 20 64 65 6E 67 6B 65 6E 67 seme By dengkeng
00000AA0 20 51 51 3A 32 38 38 39 35 37 35 31 00 00 00 00 QQ:28895751....
我们可以看到在我们添加的2个IID结构后面有1个全0的IID,以标志其结束,在结束的标志
后面我们添加了DLL名"user32.dll",所以第二个IID中的Name1字段填入00004044,使其指向
"user32.dll",接下来是添加我们所需的API,MessageBoxA,为了方便我们在0xA50处添加,当然
我们也可以在0xA4F处添加,那样填写FirstThunk就不好看了,所以我们从0xA50开始,前面两个
字为00 00,代表Hint,接下来就是填写MessageBoxA,好了现在我们在结束的IID后面添加一个
API的RVA,即00004050,使我们添加的第二个IID中的FirstThunk指向它,所以我们在第二个IID
中的FirstThunk中写入的内容为0000403C.
还有重要的一点的说明是在结束的IID后面添加API函数的RVA应该以双字为0的内容结束,
即0xA40到0xA43为0,我就是因为少考虑了这一点最后修改的程序出了错误!切记,切记!!!!
好了我们在0xA70和0xA80添加Caption和Text,好了现在我们需要做的就是修改Import Table
的起始地址和长度了:
在PE头偏移0x80处这里是0xB0+0x80=0x130
Change To:
修改起始RVA=>|| ||<=Size,3个IID长度
/ /
00000130 00 40 00 00 3C 00 00 00 00 00 00 00 00 00 00 00 .@..,...........
最后我们需要修改的就是程序的入口地址了(病毒??),AddressOfEntryPoint在PEHeadr的偏移
0x28处,我们这里是0xB0+0x28=0xD8处:
修改为000040B0(RVA)=>||<=因为我们是在0xAA0结束,我们将在0xAB0开始Write Code
/
000000D0 00 04 00 00 00 00 00 00 B0 40 00 00 00 10 00 00 ........燖......
下面的工作就是写Code了,不多只要几句话,当然我们有必要了解一下,MessageBox结构:
int MessageBox(
HWND hWnd, // handle of owner window
LPCTSTR lpText, // address of text in message box
LPCTSTR lpCaption, // address of title of message box
UINT uType // style of message box
);
我们拿出Hiew,Go,Let Write Code....
我们依次从右至左,Push
push 0 ;uType
push 404070 ;Caption
push 404080 ;Text
push 0 ;hWnd
call d,[40403C] ;Call d,[ImageBase+FirstThunkRVA]
push 401000
ret ;Function ret just as jmp 401000
F9存盘运行,Yeah,看到弹出的MessageBox了吗???
Made By dengkeng
E-mail:shellc0de@sohu.com
欢迎转载,请保持文章的完整性