- 博客(0)
- 资源 (6)
- 问答 (1)
- 收藏
- 关注
程序自效验去除经典教程集
程序载入OD
下断bp CreateFileA,F9运行
OD中断,ALT+F9执行到用户代码
下面就是F8单步跟踪了
程序在0048EE23处出现对话框,很明显,在0048EDF9处的跳转就是关键跳了
直接将0048EDF9 /7E 38 jle short dumped_.0048EE33
改成0048EDF9 /7E 38 jmp dumped_.0048EE33
保存下,运行成功
把脱好的程序载入ResScope,发现有非标准资源结构,那就用Fix Resource修正下资源,再次再入ResScope,这次可以修改资源了,但是问题又来了。。。
打开修正好的程序,程序只是一闪而过就自动关闭了,看来还有校验,继续操起OD,再次载入程序
下断bp CreateFileA,F9运行
OD中断,ALT+F9执行到用户代码,继续F8单步走
0048EE5F出OD就会跑飞了,显然0048EE5D处的跳转又是关键跳啦,
把0048EE5D /74 05 je short 1.0048EE64
改成0048EE5D /74 05 jmp 1.0048EE64
就OK了,保存,运行一切正常
现在程序太大,我们再用CxLrb大侠汉化的Resource Binder V2.6处理一下!
挖塞,程序一下从154M缩小到1.13 MB,这样的结果还是让人满意的
但是一运行,程序又是一闪而过,还有校验,OK,继续
OD载入程序,这次可能会比较卡
下断bp CreateFileA,F9运行
OD中断,ALT+F9执行到用户代码,继续F8单步走
0048EE3F处OD跑飞,也很明显了0048EE3D处就是关键跳啦,
把0048EE3D . /74 05 je short 2.0048EE44
改成0048EE3D . /74 05 jmp 2.0048EE44
保存,运行成功,感觉048EE4A处的跳转应该也是个校验吧,只是没用到,程序处理到这里就差不多了,有是不妥之处还望大侠们指点!
2010-12-01
OD反汇编语言解释.doc
32位CPU所含有的寄存器有:
4个数据寄存器(EAX、EBX、ECX和EDX)
2个变址和指针寄存器(ESI和EDI) 2个指针寄存器(ESP和EBP)
6个段寄存器(ES、CS、SS、DS、FS和GS)
1个指令指针寄存器(EIP) 1个标志寄存器(EFlags)
1、数据寄存器
数据寄存器主要用来保存操作数和运算结果等信息,从而节省读取操作数所需占用总线和访问存储器的时间。
32位CPU有4个32位的通用寄存器EAX、EBX、ECX和EDX。
对低16位数据的存取,不会影响高16位的数据。
这些低16位寄存器分别命名为:AX、BX、CX和DX,它和先前的CPU中的寄存器相一致。
4个16位寄存器又可分割成8个独立的8位寄存器(AX:AH-AL、BX:BH-BL、CX:CH-CL、DX:DH-DL),每个寄存器都有自己的名称,可独立存取。
程序员可利用数据寄存器的这种“可分可合”的特性,灵活地处理字/字节的信息。
寄存器EAX通常称为累加器(Accumulator),用累加器进行的操作可能需要更少时间。可用于乘、 除、输入/输出等操作,使用频率很高;
寄存器EBX称为基地址寄存器(Base Register)。它可作为存储器指针来使用;
寄存器ECX称为计数寄存器(Count Register)。
在循环和字符串操作时,要用它来控制循环次数;在位操作中,当移多位时,要用CL来指明移位的位数;
寄存器EDX称为数据寄存器(Data Register)。在进行乘、除运算时,它可作为默认的操作数参与运算,也可用于存放I/O的端口地址。
在16位CPU中,AX、BX、CX和DX不能作为基址和变址寄存器来存放存储单元的地址,
在32位CPU中,其32位寄存器EAX、EBX、ECX和EDX不仅可传送数据、暂存数据保存算术逻辑运算结果,
而且也可作为指针寄存器,所以,这些32位寄存器更具有通用性。
2、变址寄存器
32位CPU有2个32位通用寄存器ESI和EDI。
其低16位对应先前CPU中的SI和DI,对低16位数据的存取,不影响高16位的数据。
寄存器ESI、EDI、SI和DI称为变址寄存器(Index Register),它们主要用于存放存储单元在段内的偏移量,
用它们可实现多种存储器操作数的寻址方式,为以不同的地址形式访问存储单元提供方便。
变址寄存器不可分割成8位寄存器。作为通用寄存器,也可存储算术逻辑运算的操作数和运算结果。
它们可作一般的存储器指针使用。在字符串操作指令的执行过程中,对它们有特定的要求,而且还具有特殊的功能。
3、指针寄存器
其低16位对应先前CPU中的BP和SP,对低16位数据的存取,不影响高16位的数据。
32位CPU有2个32位通用寄存器EBP和ESP。
它们主要用于访问堆栈内的存储单元,并且规定:
EBP为基指针(Base Pointer)寄存器,用它可直接存取堆栈中的数据;
ESP为堆栈指针(Stack Pointer)寄存器,用它只可访问栈顶。
寄存器EBP、ESP、BP和SP称为指针寄存器(Pointer Register),主要用于存放堆栈内存储单元的偏移量,
用它们可实现多种存储器操作数的寻址方式,为以不同的地址形式访问存储单元提供方便。
指针寄存器不可分割成8位寄存器。作为通用寄存器,也可存储算术逻辑运算的操作数和运算结果。
4、段寄存器
段寄存器是根据内存分段的管理模式而设置的。内存单元的物理地址由段寄存器的值和一个偏移量组合而成
的,这样可用两个较少位数的值组合成一个可访问较大物理空间的内存地址。
CPU内部的段寄存器:
ECS——代码段寄存器(Code Segment Register),其值为代码段的段值;
EDS——数据段寄存器(Data Segment Register),其值为数据段的段值;
EES——附加段寄存器(Extra Segment Register),其值为附加数据段的段值;
ESS——堆栈段寄存器(Stack Segment Register),其值为堆栈段的段值;
EFS——附加段寄存器(Extra Segment Register),其值为附加数据段的段值;
EGS——附加段寄存器(Extra Segment Register),其值为附加数据段的段值。
..................................
2010-11-28
几种常用脱壳方法讲解
几种常用脱壳方法讲解
作者:★闯☆≈荡≈
------赠送好友"随风£煦雨ぃ" QQ:512642907
文件大小:解压后51MB 源文件21MB
动画性质:教程讲解
类型格式:屏幕录像专家
使用工具:peid od
第一种:ESP定律脱壳法
第二种:万能断点法
第三种:SFX自动脱壳法
第四种:EBP跟踪法
第五种:直接找出口断点法
第六种:内存镜像断点法
2010-11-28
DK网络手脱VB的VMP壳
VirtualProtect
00401262 76 62 36 63 68 73 2E 64 6C 6C 00 vb6chs.dll.
DELPHI加出来的区段是VMP2
VB 加出来的区段是.vmp1
2011-02-15
脱壳优化+去自效验 电子书
自校检是许多软件的保护手段之一,对软件加个简单的壳再增加自校检在一定程序上可以抵挡住一大部分新手,不过,对许多人来说,这个保护已经很弱了。可是,搜索论坛,居然没有一篇系统的文章。不知道是大家太忙了还是因为要守住点秘密。其实大部分技术应该拿出来交流才好,只有交流才有进步。就象老王的EPE,netsowell一次一次的脱壳文章,才促使老王一次一次的升级,保护强度也越来越强。废话一堆,不讲了。下面讲几种常见的解决自校检方法,写的粗略,希望大家补充。
1、通用对比法。就是将已经触发自校检的程序与原来正常的程序进行关键跳转对比,这种方法比较通用,大部分的自校检可以通过此方法解决(如果软件有防多开窗口的限制,需
要先解决这个问题。)附件中的sample1.EXE是一个加了ASPACK的自校检程序,修改任何代码或大小等都会触发校检提示软件被修改。dumped.EXE是脱壳后的文件,由于触发校检运行后出现“文件被非法修改”的提示,现在我们来解决脱壳后文件的自校检问题。打开脱壳后的程序dumped.EXE,下断BP CreateFileA,F9两次后出现出错提示。CTRL+F2重新载入dumped.EXE,下断BP reateFileA,F9一次。这时另开一个OD打开原来的程序sample1.EXE,用脚本到达OEP,命令中也下断BP CreateFileA,F9一次,这时两个OD停在同一个地方,然后在两个OD中逐步单步跟踪,碰到JE、JNE、JBE...之类的关键跳转要对比一下两者的区别。
7C801A24 > 8BFF MOV EDI,EDI ; BP CreateFileA断在这里,ALT+F9返回
7C801A26 55 PUSH EBP
=================
0040111C |. 3BF4 CMP ESI,ESP ; 都停在这里,逐步F8,进行关键跳转的对比
0040111E |. E8 0D030000 CALL crcdumpe.00401430
00401123 |. 8985 E0FEFFFF MOV DWORD PTR SS:[EBP-120],EAX
00401129 |. 83BD E0FEFFFF>CMP DWORD PTR SS:[EBP-120],-1
00401130 |. 75 07 JNZ SHORT crcdumpe.00401139
逐步F8,跟到下面的代码时,发现两个跳转不一样:
0040120C /75 07 JNZ SHORT crc.00401215 ; 原版这个地方信息窗口提示:跳转没有实现
0040120E |B8 01000000 MOV EAX,1
00401213 |EB 02 JMP SHORT crc.00401217
00401215 \33C0 XOR EAX,EAX
=======================
0040120C |. /75 07 JNZ SHORT crcdumpe.00401215 ; 脱壳版这个地方信息窗口提示:跳转已经实现,NOP掉
0040120E |. |B8 01000000 MOV EAX,1
00401213 |. |EB 02 JMP SHORT crcdumpe.00401217
00401215 |> \33C0 XOR EAX,EAX
这时将脱壳版0040120C处代码NOP掉后另存为dumpedFIX.EXE。试着运行一下,如果正常完事,还不行的话继续跟踪下去。该例只改这一处。
2、跟踪退出函数。附件中sample2也是个自校检程序,修改任何一处软件会自动退出。我们试着用UltraEdit将sample2.EXE的最后一个字节改为01后另存为sample2-change.EXE,这时运行sample2-change就会自动退出,我们就是要从退出函数入手。软件退出一般都是调用ExitProcess、PostQuitMessage之类的,我们用OD载入sample2-change.EXE,从输入表中我们可以看出软件是调用ExitProcess退出的。于是在OD中下断BP ExitProcess,F9运行,断下后看堆栈信息:
0012FEB8 004015B5 /CALL 到 ExitProcess 来自 sample2-.004015AF //从这里我们可以看出ExitProcess的调用地方是在004015AF
0012FEBC 00000000 \ExitCode = 0
0012FEC0 20DFA6E6
在OD中CTRL+G,输入004015AF:
004015AF |. FF15 AC514200 CALL DWORD PTR DS:[<&KERNEL32.ExitProces>; \就在这里,向上找这个子CALL的首部
004015B5 |> 8BE5 MOV ESP,EBP
004015B7 |. 5D POP EBP
004015B8 \. C3 RETN
=======================================
004014E0 /$ 55 PUSH EBP ; 找到这里,注意信息栏的内容
004014E1 |. 8BEC MOV EBP,ESP
004014E3 |. 51 PUSH ECX
004014E4 |. 833D F8354200>CMP DWORD PTR DS:[4235F8],1
004014EB |. 75 11 JNZ SHORT sample2-.004014FE
信息栏的内容:
Local Calls from 0040146B, 0040148B, 004014A9, 004014C9
也就是说有四个地方调用ExitProcess退出,因为程序的退出按钮和关闭的叉号也是调用ExitProcess函数的,一般都会在前面几个,我们在内容上右击,“前往CALL来自0040146B”
0040146B |. E8 70000000 CALL sample2-.004014E0 ; \到这里,同样查找首部
00401470 |. 83C4 0C ADD ESP,0C
00401473 |. 5D POP EBP
00401474 \. C3 RETN
============
00401460 /$ 55 PUSH EBP ; 在这里,信息栏提示:Local Calls from 00401072, <ModuleEntryPoint>+11A
00401461 |. 8BEC MOV EBP,ESP
00401463 |. 6A 00 PUSH 0 ; /Arg3 = 00000000
00401465 |. 6A 00 PUSH 0 ; |Arg2 = 00000000
在Local Calls from 00401072上右击,前往CALL来自00401072:
00401048 |. E8 BDFFFFFF CALL sample2-.0040100A
0040104D |. 85C0 TEST EAX,EAX
0040104F |. 74 1F JE SHORT sample2-.00401070 ; 是从这里跳过去的,NOP掉
00401051 |. 8BF4 MOV ESI,ESP
00401053 |. 6A 30 PUSH 30 ; /Style = MB_OK|MB_ICONEXCLAMATION|MB_APPLMODAL
00401055 |. 68 28004200 PUSH sample2-.00420028 ; |Title = "提示"
0040105A |. 68 1C004200 PUSH sample2-.0042001C ; |Text = "正常运行!"
0040105F |. 6A 00 PUSH 0 ; |hOwner = NULL
00401061 |. FF15 B4524200 CALL DWORD PTR DS:[<&USER32.MessageBoxA>>; \MessageBoxA
00401067 |. 3BF4 CMP ESI,ESP
00401069 |. E8 82050000 CALL sample2-.004015F0
0040106E |. EB 07 JMP SHORT sample2-.00401077
00401070 |> 6A 00 PUSH 0
00401072 |. E8 E9030000 CALL sample2-.00401460 ; 就是这里了,最终会调用ExitProcess,向上看是从哪里跳过来
00401077 |> 33C0 XOR EAX,EAX
可以看出,00401072处的CALL最终呼叫ExitProcess退出,所以只要使0040104F处的跳转失效即可,将0040104F的跳转NOP掉后保存,测试运行正常。
三、利用第三方软件辅助查找关键的地方。很多软件利用CRC或者MD5实现磁盘文件校验或者内存映像校验等,对此类软件我们可以利用算法识别工具找到密码学算法和核心,然后层层向上,找到最初的调用地方更改其流程方向。还是附件中的sample1.EXE,脱壳的文件为dumped.EXE,我们来解决这个软件的自校检。先用PEID的插件kanal分析dumped.EXE所采的密码学算法,如图,
可以看出,软件采用了CRC算法,算法特征码出现在0040131C,就从这里入手,OD载入dumped.EXE,CTRL+G搜索0040131C:
0040131C |? 2083 B8ED898D AND BYTE PTR DS:[EBX+8D89EDB8],AL ; 找到的地方在这里,上拉找到这个CALL的首部
00401322 |? FC CLD
00401323 |? FB STI
00401324 |? FFFF ??? ; 未知命令
00401326 |. EB 0E ||JMP SHORT crcdumpe.00401336
00401328 |> 8B95 FCFBFFFF ||MOV EDX,DWORD PTR SS:[EBP-404]
0040132E |. D1EA ||SHR EDX,1
00401330 |. 8995 FCFBFFFF ||MOV DWORD PTR SS:[EBP-404],EDX
00401336 |>^ EB B5 |\JMP SHORT crcdumpe.004012ED
00401338 |> 8B85 F8FBFFFF |MOV EAX,DWORD PTR SS:[EBP-408]
0040133E |. 8B8D FCFBFFFF |MOV ECX,DWORD PTR SS:[EBP-404]
00401344 |. 898C85 00FCFF>|MOV DWORD PTR SS:[EBP+EAX*4-400],ECX
0040134B |.^ E9 6AFFFFFF \JMP crcdumpe.004012BA
============================
00401290 /> \55 PUSH EBP ; 到这里,看OD的提示栏:Jump from 00401005,从00401005跳转来的
00401291 |. 8BEC MOV EBP,ESP
00401293 |. 81EC 50040000 SUB ESP,450
00401299 |. 53 PUSH EBX
0040129A |. 56 PUSH ESI
在Jump from 00401005上右击,“前往JMP 来自00401005”
00401005 $ /E9 86020000 JMP crcdumpe.00401290 ; 到这里,看信息栏内容:Local Call from 00401201,00401201处的CALL调用这里
0040100A $ |E9 B1000000 JMP crcdumpe.004010C0
在Local Call from 00401201上右击,“前往CALL 来自00401201”
00401201 |. E8 FFFDFFFF CALL crcdumpe.00401005 ; 到这里,再向上找到这个CALL的顶部
00401206 |. 83C4 08 ADD ESP,8
==================
004010C0 /> \55 PUSH EBP ; 到这里,看任务栏信息:Jump from 0040100A
004010C1 |. 8BEC MOV EBP,ESP
004010C3 |. 81EC 64010000 SUB ESP,164
在Jump from 0040100A上右击,“前往JMP 来自0040100A”
0040100A $ /E9 B1000000 JMP crcdumpe.004010C0 ; 到这里,继续根据任务栏信息向上找:Local Call from 00401048
0040100F $ |E9 1C000000 JMP crcdumpe.00401030
在Local Call from 00401048上右击,“前往CALL 来自00401048”
00401048 |. E8 BDFFFFFF CALL crcdumpe.0040100A ; 就是这里了,计算CRC并进行对比的CALL
0040104D |. 85C0 TEST EAX,EAX
0040104F |. 74 1F JE SHORT crcdumpe.00401070 ; 这里就是关键跳转了,NOP掉
00401051 |. 8BF4 MOV ESI,ESP
00401053 |. 6A 30 PUSH 30 ; /Style = MB_OK|MB_ICONEXCLAMATION|MB_APPLMODAL
00401055 |. 68 40004200 PUSH crcdumpe.00420040 ; |Title = "提示"
0040105A |. 68 34004200 PUSH crcdumpe.00420034 ; |Text = "正常运行!"
0040105F |. 6A 00 PUSH 0 ; |hOwner = NULL
00401061 |. FF15 B4524200 CALL DWORD PTR DS:[<&user32.MessageBoxA>>; \MessageBoxA
更改0040104F处的跳转后保存为dumpedFIX,运行正常。
四、对付校检自身大小的软件的一般方法。也有许多软件,利用CHECKSUM、FILELEN等在代码中对本身的大小做了标记,如果发现大小变了就自动退出。附件中的FILELEN就是这样的,FILELEN-UNPACK.EXE是脱壳后的软件,由于脱壳后软件大小发生了变化,所以FILELEN-UNPACK运行后就自动退出。对付这种校检,我们有个简单的方法,就是将脱壳后的软件中检测自身大小的部分改为脱壳后文件的大小。我们看一下FILELEN的大小为:10752字节转16进制为2A00,再看看脱壳后的文件FILELEN-UNPACK.EXE的大小30208字节,即7600,关键是如何找到对自身大小进行对比的语句,我们知道一般的形式都是CMP EAX,2A00,但是到底是哪个寄存器呢?EAX,EBX、ECX....,寄存器种类比较多,我们不可能每个去找,这时W32Dasm派上用场。用W32Dasm载入FILELEN-UNPACK,我们只要搜索00002A00即可,前面的部分不管它,找到在这里:
:00401B8F 81FE002A0000 cmp esi, 00002A00
右击-“HEX”,更改代码002A00为脱壳后的大小007600即可,再搜索,发现该例只有一个对比的地方,保存后运行正常。
对于VB检测自身大小的软件我们还可以跟踪FileLen函数,因为VB一般都用FileLen检测自身的大小,用OD载入FILELEN-UNPACK.EXE,下断BP rtcFileLen,F9后断下,ALT+F9返回:
00401B5E . 8BF0 MOV ESI,EAX ; 这里EAX的值就是FILELEN取得的自身的大小,EAX=00007600
00401B60 . 8D55 D4 LEA EDX,DWORD PTR SS:[EBP-2C]
00401B63 . 8D45 D8 LEA EAX,DWORD PTR SS:[EBP-28]
00401B66 . 52 PUSH EDX
00401B67 . 8D4D E0 LEA ECX,DWORD PTR SS:[EBP-20]
00401B6A . 50 PUSH EAX
00401B6B . 8D55 DC LEA EDX,DWORD PTR SS:[EBP-24]
00401B6E . 51 PUSH ECX
00401B6F . 8D45 E4 LEA EAX,DWORD PTR SS:[EBP-1C]
00401B72 . 52 PUSH EDX
00401B73 . 50 PUSH EAX
00401B74 . 6A 05 PUSH 5
00401B76 . FF15 70104000 CALL DWORD PTR DS:[<&msvbvm60.__vbaFreeS>; msvbvm60.__vbaFreeStrList
00401B7C . 8D4D CC LEA ECX,DWORD PTR SS:[EBP-34]
00401B7F . 8D55 D0 LEA EDX,DWORD PTR SS:[EBP-30]
00401B82 . 51 PUSH ECX
00401B83 . 52 PUSH EDX
00401B84 . 6A 02 PUSH 2
00401B86 . FF15 14104000 CALL DWORD PTR DS:[<&msvbvm60.__vbaFreeO>; msvbvm60.__vbaFreeObjList
00401B8C . 83C4 24 ADD ESP,24
00401B8F . 81FE 002A0000 CMP ESI,2A00 ; 这里就是利用FILELEN取得的大小与原来做的标记对比,可以改这里的2A00为7600或者更改下面的跳转
00401B95 . 75 6E JNZ SHORT FILELEN-.00401C05
00401B97 . B9 04000280 MOV ECX,80020004
好像常见的自校检就这些,我不知道还有没有其它的,如果有希望大家能够补充完善。
2010-12-01
MYSQL 多重查询多重匹配问题
2021-10-21
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅