A homemade shell shelling

1. check operation housing

Because it is made of a shell, the shell tool is finding a signature, will not check hatched;

2. Determine relocation separated

If the relocation is not isolated, it will generate a random access group, resulting in failure husking

3. Find OEP

① use ESP Theorem
② find the location OEP ( OEP: 47148B )
Remember the "right" click "analysis" select "Delete analysis"

4. See import address table IAT

Having found the OEP, and the Import Address Table IAT loaded in the distance after the OEP, by a single step too, it can be found 004714B1 FF15 80504700 call dword ptr ds: [0x475080] Import Address Table IAT is loaded in this right-click at the "data window following the" select "memory address"
We can see the address of the memory address value stored in 0027XXXX position, it is a heap, and the address of the normal IAT should 7XXXXXXXX place, so, it is determined IAT is encrypted.

The encrypted position into the IAT

① hardware breakpoints in the modification of the IAT
In FIG. 00275039 hardware breakpoint at the writing position, can jump to the position of the encrypted IAT
② start again, look for modified at run
The first run, hit module is ntdll
And then continues to run, find 001E0895 , here is filled IAT
Address here is 001E0897, this is an address VA, it is to apply for an address in heap memory, so we only need to record its RVA address of 0897, while 01E0000 program is to address dynamic applications, dynamically when writing the script obtain this address.
001E0895 8902 mov dword ptr ds:[edx],eax
001E0897 E8 39000000 call 001E08D5
③ determining how the dynamic group address of the application
从新加载程序,进行单步步入跟踪,我们知道,程序比如会先加载壳代码,也就必然会开辟堆空间,,而开辟堆空间会用到VirtualAlloc,这样我们可以通过函数名快速的找到申请堆空间位置。
由图可以看到,在0047A37D处会显示字符串“ VirtualAlloc”,由此,我们确定申请的堆空间地址会直接存入eax中,再单步一下,就能看到eax寄存器中出现堆空间地址 001E0000

6.脱壳思路

此壳的加密行为为,申请一块堆空间,将原本的IAT数据写人到堆空间中,再用堆空间内存地址覆盖IAT,相当于做了一次中间转换,如果能其加密结束处将正确的IAT原始数据重新写入IAT中进行覆盖操作,就能顶掉壳的中间跳转操作,达到脱壳效果。

7.找到关键地址

①找回原始函数地址思路
我们知道了填充加密IAT的代码位置,就能找到存放原始函数API地址的堆空间,就能找回原始函数,就在执行用堆空间地址覆盖IAT代码的前不远处。
②Run追踪
我们需要使用Run跟踪来帮助我们快速找到,获得存放原始函数地址的位置。首先在填充IAT的位置,删除之前的硬件断点,再在这个位置下软件断点,点击导航栏的调试,单击“打开RUN追踪”,再选择跟踪步入
打开RUN追踪窗口,在导航栏点击“查看“,再点击“RUN追踪”即可
等待片刻
③找到关键位置
查看RUN跟踪记录的指令信息,重点关注这次循环过程中,寄存器发生的变化,从最后一条记录向前找,找寄存器中的值像真实函数地址的指令
为了确认,双击此条信息,反汇编窗口跟随,设置软件短句,运行到此处,右键单击,数据窗口跟随,点击“隐含堆栈地址”,再在数值处,右键选择“反汇编窗口中跟随”
④确认关键点
我们需要在获取函数地址指令的下一行,获取EXD的值,用来引向正确的IAT,记录其偏移 10F7
001710F6 5A pop edx ; kernel32.HeapFree
001710F7 E8 02F4FFFF call 001704FE

8.编写OD脚本恢复IAT

①准备阶段
0047148B  ==  OEP
0047A37F  ==  申请的堆空间,里面有壳代码,返回值EAX
0x0897      ==  填充IAT的下一行指令位置,我们需要用真实地址覆盖填充过的加密IAT
0x10F7      ==  获取真实函数地址的下一行,真实地址保存在EDX中

MOV ddEDX,0
MOV dwAddress,0
MOV ddGetVirtualAlloc,0047A37F
MOV dwGetFunctionRVA,10F7
MOV dwWriteIATRVA,0897
MOV ddOEPAddr,0047148B
BC
BPHWCALL
BPHWS ddGetVirtualAlloc,"x"
BPHWS ddOEPAddr,"x"
LOOP1:
RUN
GetVir:
CMP eip,ddGetVirtualAlloc
JNE CASE1
MOV dwAddress,eax
ADD dwGetFunctionRVA,dwAddress
MSG dwGetFunctionRVA
ADD dwWriteIATRVA,dwAddress
MSG dwWriteIATRVA
BPHWS dwGetFunctionRVA,"x"
BPHWS dwWriteIATRVA,"x"
JMP LOOP1
CASE1:
CMP eip,dwGetFunctionRVA
JNE CASE2
MOV ddEDX,edx
JMP LOOP1
CASE2:
CMP eip,dwWriteIATRVA
JNE CASE3
MOV [edx],ddEDX
JMP LOOP1
CASE3:
CMP eip,ddOEPAddr
JNE LOOP1
MSG "到达OEP,可以dump了!!!"
x
 
1
MOV ddEDX,0
2
MOV dwAddress,0
3
MOV ddGetVirtualAlloc,0047A37F
4
MOV dwGetFunctionRVA,10F7
5
MOV dwWriteIATRVA,0897
6
MOV ddOEPAddr,0047148B
7
BC
8
BPHWCALL
9
BPHWS ddGetVirtualAlloc,"x"
10
BPHWS ddOEPAddr,"x"
11
LOOP1:
12
RUN
13
GetVir:
14
CMP eip,ddGetVirtualAlloc
15
JNE CASE1
16
MOV dwAddress,eax
17
ADD dwGetFunctionRVA,dwAddress
18
MSG dwGetFunctionRVA
19
ADD dwWriteIATRVA,dwAddress
20
MSG dwWriteIATRVA
21
BPHWS dwGetFunctionRVA,"x"
22
BPHWS dwWriteIATRVA,"x"
23
JMP LOOP1
24
CASE1:
25
CMP eip,dwGetFunctionRVA
26
JNE CASE2
27
MOV ddEDX,edx
28
JMP LOOP1
29
CASE2:
30
CMP eip,dwWriteIATRVA
31
JNE CASE3
32
MOV [edx],ddEDX
33
JMP LOOP1
34
CASE3:
35
CMP eip,ddOEPAddr
36
JNE LOOP1
37
MSG "到达OEP,可以dump了!!!"















Guess you like

Origin www.cnblogs.com/HOPEAMOR/p/12017292.html