欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  网络运营

小菜对于TMD1.82分析

程序员文章站 2022-04-12 08:49:46
最近学习了不少牛的脱壳脚本,Tortoiser也作了不少关于脱壳视频,使得本菜学习到许多的东西,感受 大牛们的强大.自己也要努力,当然有时看脚本,有时出现这样,那样特征码.说实话我根无法知道...
最近学习了不少牛的脱壳脚本,Tortoiser也作了不少关于脱壳视频,使得本菜学习到许多的东西,感受

大牛们的强大.自己也要努力,当然有时看脚本,有时出现这样,那样特征码.说实话我根无法知道这样的特

征是在那提取的为什么要在那.要知道这些也只有自己通过实践去找到答案了.

 

     我选择的是Themida v1.8.2.0加壳程序,加壳设置除了没有选择OEP处理,其它都是默认的设置.好了

既然加好壳了我来去OEP看看吧!

     我通过对VirtualAllocEx函数下断,按Shift+F9 十九次程序运行,OK那我就按十八次后删除断点,再在代码段下

在访问上设置F2断点,断在此处。00419F77    8BF0            mov esi,eax

 

00419F79    A1 80F84400     mov eax,dword ptr ds:[0x44F880]

 

00419F7E    8906            mov dword ptr ds:[esi],eax

 

00419F80    8D56 04         lea edx,dword ptr ds:[esi+0x4]

 

00419F83    B8 ECD34400     mov eax,delphi7?0044D3EC

 

00419F88    B9 02000000     mov ecx,0x2

 

00419F8D    E8 2689FEFF     call delphi7?004028B8

 

00419F92    BA 2C9F4100     mov edx,delphi7?00419F2C

 

00419F97    8D46 05         lea eax,dword ptr ds:[esi+0x5]

 

00419F9A    E8 ADFFFFFF     call delphi7?00419F4C

 

00419F9F    8946 06         mov dword ptr ds:[esi+0x6],eax

 

00419FA2    8D5E 0A         lea ebx,dword ptr ds:[esi+0xA]

 

00419FA5    C603 E8         mov byte ptr ds:[ebx],0xE8

 

00419FA8    8D56 04         lea edx,dword ptr ds:[esi+0x4]

 

00419FAB    8BC3            mov eax,ebx

 

00419FAD    E8 9AFFFFFF     call delphi7?00419F4C

复制代码F8单步会来到:0044 CAA8    A1 B8DF4400     mov eax,dword ptr ds:[0x44DFB8]

 

0044CA AD    8B00            mov eax,dword ptr ds:[eax]

 

0044CAAF     E8 9CE6FFFF     call delphi7?0044B150

 

0044CAB4     8B0D 94E04400   mov ecx,dword ptr ds:[0x44E094]                     ; delphi7?0044FBD0

 

0044CABA    A1 B8DF4400     mov eax,dword ptr ds:[0x44DFB8]

 

0044CABF    8B00            mov eax,dword ptr ds:[eax]

 

0044CAC1    8B15 F0C64400   mov edx,dword ptr ds:[0x44C6F0]                     ; delphi7?0044C73C

 

0044CAC7    E8 9CE6FFFF     call delphi7?0044B168

 

0044CACC    A1 B8DF4400     mov eax,dword ptr ds:[0x44DFB8]

 

0044CAD1    8B00            mov eax,dword ptr ds:[eax]

 

0044CAD3    E8 10E7FFFF     call delphi7?0044B1E8

 

0044CAD8    E8 4372FBFF     call delphi7?00403D20

 

0044CADD    8D40 00         lea eax,dword ptr ds:[eax]

复制代码向上拉就看到这段代挺像delphi程序0044CA98    55              push ebp

 

0044CA99    8BEC            mov ebp,esp

 

0044CA9B    83C4 F0         add esp,-0x10

 

0044CA9E    B8 B8C84400     mov eax,delphi7?0044C8B8

 

0044CAA3    E8 2091FBFF     call delphi7?00405BC8

 

0044CAA8    A1 B8DF4400     mov eax,dword ptr ds:[0x44DFB8]

 

0044CAAD    8B00            mov eax,dword ptr ds:[eax]

 

0044CAAF    E8 9CE6FFFF     call delphi7?0044B150

 

0044CAB4    8B0D 94E04400   mov ecx,dword ptr ds:[0x44E094]                     ; delphi7?0044FBD0

 

0044CABA    A1 B8DF4400     mov eax,dword ptr ds:[0x44DFB8]

 

0044CABF    8B00            mov eax,dword ptr ds:[eax]

 

0044CAC1    8B15 F0C64400   mov edx,dword ptr ds:[0x44C6F0]                     ; delphi7?0044C73C

 

0044CAC7    E8 9CE6FFFF     call delphi7?0044B168

 

0044CACC    A1 B8DF4400     mov eax,dword ptr ds:[0x44DFB8]

 

0044CAD1    8B00            mov eax,dword ptr ds:[eax]

 

0044CAD3    E8 10E7FFFF     call delphi7?0044B1E8

 

0044CAD8    E8 4372FBFF     call delphi7?00403D20

 

0044CADD    8D40 00         lea eax,dword ptr ds:[eax

复制代码我们去第一个CALL里看看,可以到jmp [xxxxxxxx]被处理成这样记个来吧00405B04    90              nop

 

00405B05  - E9 56B26D02     jmp 02AE0D60

 

00405B0A    8BC0            mov eax,eax

 

00405B0C    90              nop

 

00405B0D  - E9 DEAD6D02     jmp 02AE08F0

 

00405B12    8BC0            mov eax,eax

 

00405B14    90              nop

 

00405B15  - E9 9FAC6D02     jmp 02AE07B9

 

00405B1A    8BC0            mov eax,eax

 

00405B1C    90              nop

 

00405B1D  - E9 78A96D02     jmp 02AE049A

复制代码好了重载OD,既然加壳软件对代码作了处理.那我们就去跟一跟是乍样处理的吧!对代码段处理了就应对

代码进行写操作吧!!!打开内存镜像在代码段下内存访问断点,不停按Shift+F9 ,注意寄存器窗口.如果出现API

函数时,停下来

EAX 0045011C delphi7?0045011C

ECX 7C9210E0 ntdll.RtlLeaveCriticalSection

EDX 5DECA5C2

EBX 006BF497 delphi7?006BF497

ESP 0012FF64

EBP F6E56041

ESI 006B922D delphi7?006B922D

EDI 7C9210E0 ntdll.RtlLeaveCriticalSection

EIP 006BF364 delphi7?006BF364程序就断到此处了

 

006BF364    8908            mov dword ptr ds:[eax],ecx                  ; ntdll.RtlLeaveCriticalSection

 

//////////////////////////

 

mov dword ptr ds:[eax],ecx  

 

注意此句汇编它把ECX的数据写到某个地址去

 

而此时ECX存放的是API的地址,这里可能是填充API的地方

 

数据窗口地址跟随一下看看

 

00450114  00000000

 

00450118  029E0000

 

0045011C  00000000

 

00450120  00000000

 

00450124  00000000

 

00450128  00000000

 

0045012C  00000000

 

00450130  00000000

 

00450134  00000000

 

00450138  00000000

 

0045013C  00000000

 

00450140  00000000

 

eax == 0045011C,0045011C现在数据是0,单步一下在观察

 

00450114  00000000

 

00450118  029E0000

 

0045011C  7C9210E0  ntdll.RtlLeaveCriticalSection

 

00450120  00000000

 

00450124  00000000

 

/////////////////////////

 

006BF366    AD              lods dword ptr ds:[esi]

 

006BF367    C746 FC 0000000>mov dword ptr ds:[esi-0x4],0x0

 

006BF36E    89B5 051F7409   mov dword ptr ss:[ebp+0x9741F05],esi

 

006BF374    83F8 FF         cmp eax,-0x1

 

006BF377    0F85 20000000   jnz delphi7?006BF39D

 

006BF37D    813E DDDDDDDD   cmp dword ptr ds:[esi],0xDDDDDDDD

 

006BF383    0F85 14000000   jnz delphi7?006BF39D

 

006BF389    C706 00000000   mov dword ptr ds:[esi],0x0

 

006BF38F    83C6 04         add esi,0x4

 

006BF392    89B5 051F7409   mov dword ptr ss:[ebp+0x9741F05],esi

 

006BF398  ^ E9 EDF6FFFF     jmp delphi7?006BEA8A

复制代码取消断点F9运行,出现程序界面再到数据窗口,Ctrl+G 0045011C  去

看看会发现从00450118-004506D4

00450638  02E404EF

0045063C  02E4074C

00450640  02E409D9

00450644  02E50000

00450648  02E50383

0045064C  00000000

00450650  02E503DC

00450654  00000000

00450658  770FAB10  OLEAUT32.SafeArrayPtrOfIndex

0045065C  770F515A  OLEAUT32.SafeArrayGetUBound

00450660  770F51A6  OLEAUT32.SafeArrayGetLBound

00450664  770FAA55  OLEAUT32.SafeArrayCreate

00450668  770F6BBB  OLEAUT32.VariantChangeType

0045066C  770F4CFD  OLEAUT32.VariantCopy

00450670  770F48F0  OLEAUT32.VariantClear

00450674  770F4950  OLEAUT32.VariantInit

既有API函数也有一些有规律未知数值,因此基本可以确认

006BF364    8908            mov dword ptr ds:[eax],ecx  

这段代码在处理IAT

   重载OD 在006BF364 处下硬件执行断点,F9运行断下来了!!!!!!!!!!!!!!006BF364    8908            mov dword ptr ds:[eax],ecx

 

006BF366    AD              lods dword ptr ds:[esi]

 

006BF367    C746 FC 0000000>mov dword ptr ds:[esi-0x4],0x0

 

006BF36E    89B5 051F7409   mov dword ptr ss:[ebp+0x9741F05],esi

 

006BF374    83F8 FF         cmp eax,-0x1

 

006BF377    0F85 20000000   jnz delphi7?006BF39D

复制代码F8单步这非常大的回跳

006BF458  ^ E9 11FFFFFF     jmp delphi7?006BF36E

继续F8吧注意这句代码,这句是从某个地址取出kernel32的基址

006BEC2C    8B0B            mov ecx,dword ptr ds:[ebx]               ; kernel32.7C80000ds

[ebx]==[02820000]=7C800000 (kernel32.7C800000)

继续F8吧来到006BEC9B再单步一下

006BEC9B    FFD3            call ebx

006BEC9D    83BD 71297409 0>cmp dword ptr ss:[ebp+0x9742971],0x0

寄存窗口出现了API的地址

EAX 7C9210E0 ntdll.RtlLeaveCriticalSection

ECX 7C800000 kernel32.7C800000

EDX 5DECA5C2

EBX 006BF497 delphi7?006BF497

ESP 0012FF64

EBP F6E56041

ESI 006B9229 delphi7?006B9229

EDI 0040136D delphi7?0040136D

EIP 006BECA4 delphi7?006BECA4

继续F8吧又会来到

006BF364    8908            mov dword ptr ds:[eax],ecx 

我们来总结一下吧.

1.通过006BEC9D上面的一系列运算得到API函数的地址

2.通过判断该API是否要加密,要加密就进行运算,并把结果填充入IAT

不加密就直接填充API               

3.我们写个简单脚本测试一下吧

bphwcall

 

var  addr

bphws  006BEC9B  ,"x"

bphws  006BF364,"x"

bphws  0044CA98,"x"

loop:

esto

cmp  eip,0044CA98

je  exit

cmp eip,006BF364

je  ssss

sto 

sto

mov  addr,eax

esto

sto

mov  [eax],addr

jmp  loop

ssss:

sto

jmp loop

exit:

ret

脚本跑完去看看效果

00450118  7C93137A  ntdll.RtlDeleteCriticalSection

0045011C  7C9210E0  ntdll.RtlLeaveCriticalSection

00450120  7C921000  ntdll.RtlEnterCriticalSection

00450124  7C809F91  kernel32.InitializeCriticalSection

00450128  7C809B84  kernel32.VirtualFree

0045012C  7C809AF1  kernel32.VirtualAlloc

00450130  7C8099CF  kernel32.LocalFree

00450134  7C809A2D  kernel32.LocalAlloc

00450138  7C81127A  kernel32.GetVersion

0045013C  7C8097D0  kernel32.GetCurrentThreadId

00450140  7C80981A  kernel32.InterlockedDecrement

00450144  7C809806  kernel32.InterlockedIncrement

00450148  7C80BA71  kernel32.VirtualQuery

0045014C  7C80A174  kernel32.WideCharToMultiByte

00450150  7C809C98  kernel32.MultiByteToWideChar

00450154  7C80BE56  kernel32.lstrlenA

00450158  7C8101B1  kernel32.lstrcpynA

0045015C  7C801D53  kernel32.LoadLibraryExA

00450160  7C80A4B5  kernel32.GetThreadLocale

00450164  7C801EF2  kernel32.GetStartupInfoA

00450168  7C80AE40  kernel32.GetProcAddress

0045016C  7C80B741  kernel32.GetModuleHandleA

00450170  7C80B56F  kernel32.GetModuleFileNameA

00450174  7C80D302  kernel32.GetLocaleInfoA

00450178  7C812FBD  kernel32.GetCommandLineA

0045017C  7C80AC7E  kernel32.FreeLibrary

00450180  7C813879  kernel32.FindFirstFileA

00450184  7C80EE77  kernel32.FindClose

00450188  7C81CB12  kernel32.ExitProcess

0045018C  7C810E27  kernel32.WriteFile

00450190  7C863FCA  kernel32.UnhandledExceptionFilter

00450194  7C94ABC5  ntdll.RtlUnwind

00450198  7C812AA9  kernel32.RaiseException

看样子挺OK好了IAT修复一半,接就搞定

 

看样子挺OK好了IAT修复一半,接就搞定

00405B04    90              nop

00405B05  - E9 56B26D02     jmp 02AE0D60

00405B0A    8BC0            mov eax,eax

重载OD,在数据窗口Ctrl+g到00405B04地址看看并设置成反汇编显示

00405B04    AF              scas dword ptr es:[edi]

00405B05    CD 06           int 0x6

00405B07    38DE            cmp dh,bl

00405B09    BC 5B1D18BE     mov esp,0xBE181D5B

00405B0E    D5 E5           aad 0xE5

00405B10    C3              retn

00405B11    67:B8 A9BA344C  mov eax,0x4C34BAA9

在00405B0D下硬件写入断点F9运行两次断下来了

数据窗口显示

00405B03    90              nop

00405B04    90              nop

00405B05    90              nop

00405B06    90              nop

00405B07    90              nop

00405B08    90              nop

00405B09    90              nop

00405B0A    8BC0            mov eax,eax

00405B0C    90              nop

00405B0D    90              nop

00405B0E    90              nop

00405B0F    90              nop

00405B10    90              nop

00405B11    90              nop

00405B12    8BC0            mov eax,eax

 

这段代码负责填充9090909090,这不是我想要的,取消断点

00405B0C    90              nop

00405B0D    90              nop

00405B0E    90              nop

00405B0F    90              nop

00405B10    90              nop

00405B11    90              nop

00405B12    8BC0            mov eax,eax

下个内存写入断点,F9运行断在了,

006BF44F    AB              stos dword ptr es:[edi]

F8单步后数据窗口显示00405B0D被填充了

//////////////////////////////////////////////////////

数据窗口:

00405B06    90              nop

00405B07    90              nop

00405B08    90              nop

00405B09    90              nop

00405B0A    8BC0            mov eax,eax

00405B0C    90              nop

00405B0D  - E9 A3AE6D02     jmp 02AE09B5

00405B12    8BC0            mov eax,eax

 

EAX 026DAEA3

ECX 02AE09B5

EDX 029C03F6

EBX 006B2436 delphi7?006B2436

ESP 0012FF60

EBP F6E56041

ESI 006B968D delphi7?006B968D

EDI 00405B12 delphi7?00405B12

EIP 006BF450 delphi7?006BF450

 

////////////////////////////////////////////////////////

006BF450    AD              lods dword ptr ds:[esi]

006BF451    C746 FC 0000000>mov dword ptr ds:[esi-0x4],0x0

006BF458  ^ E9 11FFFFFF     jmp delphi7?006BF36E

我们发现006BF44F    AB              stos dword ptr es:[edi]填充后

再无其他地址对它进行写操作.因此我们要处理

00405B0C    90              nop

00405B0D  - E9 A3AE6D02     jmp 02AE09B5

单步到006BF458这个地址最最好的位置

提取一下特征码AB AD C7 46 FC 00 00 00 00

接下来应该对00405B04进行填充

00405B03    90              nop

00405B04    90              nop

00405B05    90              nop

00405B06    90              nop

00405B07    90              nop

00405B08    90              nop

00405B09    90              nop

00405B0A    8BC0            mov eax,eax

我们载入无壳delphi程序进入第一个CALL

00405B03      90            nop

00405B04   $- FF25 E4014500 jmp dword ptr ds:[<&kernel32.GetModuleHa>;  kernel32.GetModuleHandleA

00405B0A      8BC0          mov eax,eax

00405B0C   $- FF25 E0014500 jmp dword ptr ds:[<&kernel32.LocalAlloc>>;  kernel32.LocalAlloc

00405B12      8BC0          mov eax,eax

00405B14   $- FF25 DC014500 jmp dword ptr ds:[<&kernel32.TlsGetValue>;  kernel32.TlsGetValue

00405B1A      8BC0          mov eax,eax

00405B1C   $- FF25 D8014500 jmp dword ptr ds:[<&kernel32.TlsSetValue>;  kernel32.TlsSetValue

可以看出如果不对此地址代码处理那么应该写回

00405B03      90            nop

00405B04   $- FF25 E4014500 jmp dword ptr ds:[<&kernel32.GetModuleHa>;  kernel32.GetModuleHandleA

好了不多说了单步F8一直来到

006BEC9B    FFD3            call ebx

006BEC9D    83BD 71297409 0>cmp dword ptr ss:[ebp+0x9742971],0x0

提取一下特征码

查看一下寄存器

EAX 7C80B741 kernel32.GetModuleHandleA

ECX 7C800000 kernel32.7C800000

EDX 5DECA5C2

EBX 006BF497 delphi7?006BF497

ESP 0012FF64

EBP F6E56041

ESI 006B9699 delphi7?006B9699

EDI 00405B12 delphi7?00405B12

EIP 006BEC9D delphi7?006BEC9D

发现EAX中的数据是GetModuleHandleA的地址OK.这不正是要写回00405B04这个地址的函数!!!!

 

但是单步再走到

006BF44F    AB              stos dword ptr es:[edi]

006BF450    AD              lods dword ptr ds:[esi]

006BF451    C746 FC 0000000>mov dword ptr ds:[esi-0x4],0x0

却发现被处理成了

00405B04    90              nop

00405B05  - E9 56B26D02     jmp 02AE0D60

好了我单步跟了这段代码得到从以下信息整理:

1.在006BEC9B    FFD3            call ebx过后寄存器出的API函数地址正是006BF44F    AB              stos dword ptr es:[edi]

处理掉的函数.

2.因此我只需要006BF44F    AB              stos dword ptr es:[edi]执行完后把006BEC9B    FFD3            call ebx得到的

函数地址写回去就OK.

3.因为IAT前面已修复,我可以将在006BEC9B    FFD3            call ebx获取的API函数地址与IAT表进行

比对,在IAT中找到相应API存放地址(xxxxxxxx).

4.找API存放地址(xxxxxxxx).就可以把jmp 02AE0D60修复成 jmp [xxxxxxxx]