[软件名称]: DZIP32.zip(脱壳后,注意该Dll可能会被杀毒软件提示为病毒,请放到虚拟机上测试,本人不对 该dzip32.dll对你所造成的任何损失负责)
Delphi7 文件对比.zip
[应用平台]:Win9X/NT/2000/XP
[软件大小]:1.91M
[破解声明]:为了检验自己的逆向破解能力。顺便感谢一下党,感谢国家
[破解工具]:PEiD,IDA 5.5,PE Explore
[备注] 我们家的曾曾已经离开我啦,程序员真悲剧,自己心爱的女人都不能留住!没有钱什么都是假的。
这个dll实现木马的功能,这是一款真正有一点商业价钱的东西,主要是实现456游戏平台的斗牛游戏的转帐功能,很有代表性,我跟踪分析了该Dll差不多1个多月的时间,重新学习了Delphi编程知识,现在想起来挺佩服那段时间的毅力,还用rose 把整个dll流程逆向出来,哈哈。 该dll由delphi 编译的,涉及到脱壳,虚拟机检测,调试检测,dll hack,socket 通信知识,窗口界面操作,多线程知识,很有代表性。
[作者]:INightElf 邮箱:INightElf@126.com
[破解日期]:2012-10-06
先放两张Rational Rose 图片,这是dzip32.dll 入口。谁知道Rational rose 2003 模型可不可以直接转出图片呢。这样截成两张图片挺难看的。
写这篇文章估计要耗费很长的时间,我会把其中涉及到的方方面面都写出来。敬请期待
在分析的过程之中,INighElf 也学习到了很多知识,决定把破解的过程详细的记录一下
1. Dll劫持篇
所谓dll 劫持指的是利用自定义的dll文件,优先取得同名dll系统文件的控制权,以实现无需修改可执行文件,而到达自动加载该dll文件的目的.
实现该机制的原理是:在window 操作系统,可执行文件加载dll动态库的顺序: 可执行文件加载器首先在该程序的目录下面搜索依赖dll文件,当程序目录下面不存在该dll文件,则继续搜索系统目录,C:/windows/system/
以654游戏平台为例子,该游戏平台可执行文件Lobby.exe,依赖dzip32.dll系统库,于是在该Lobby.exe目录下面放置自定义的dzip32.dll,该自定义的动态链接库导出函数必须和系统的导出函数一致,这样便能实现自动加载,而到达劫持系统dll文件.
1. DllEntryPoint函数是装载dll的入口,自定义dzip32.dll 首先获取系统文件dzip32.dll的路径如”C:/windows/system/dzip32.dll”
2. 调用LoadLibraryA 函数手动加载系统文件dzip32.dll库
3. 调用GetProAdrress 获取系统文件dzip32.dll 所有的导出函数的地址
4. 把自定义的dzip32.dll导出函数地址替换成为系统文件的导出函数的地址,这样便无需编写dzip32系统函数的功能,而是直接跳转.这样便实现了dll 劫持
5. 接下来的事情,你要做什么就做什么了,也是该自定义dzip32.dll的业务功能了
CODE:009D9C60 ; BOOL __stdcall DllEntryPoint(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved)
CODE:009D9C60 public DllEntryPoint
CODE:009D9C60 DllEntryPoint proc near
CODE:009D9C60
CODE:009D9C60 var_40 = dword ptr -40h
CODE:009D9C60
CODE:009D9C60 push ebp
CODE:009D9C61 mov ebp, esp
CODE:009D9C63 add esp, -40h
CODE:009D9C66 push ebx
CODE:009D9C67 push esi
CODE:009D9C68 push edi
CODE:009D9C69 xor eax, eax
CODE:009D9C6B mov [ebp+var_40], eax
CODE:009D9C6E mov eax, offset FunctionNumbers ; 函数的数量
CODE:009D9C73 call SysInit_InitLib
CODE:009D9C78 xor eax, eax
CODE:009D9C7A push ebp
CODE:009D9C7B push offset loc_9D9DA8
CODE:009D9C80 push dword ptr fs:[eax]
CODE:009D9C83 mov fs:[eax], esp
CODE:009D9C86 mov esi, offset dword_9D9DB8
CODE:009D9C8B mov edi, offset Buffer ; ""
CODE:009D9C90 mov ecx, 40h
CODE:009D9C95 rep movsd
CODE:009D9C97 push 0FFh ; uSize
CODE:009D9C9C push offset Buffer ; ""
CODE:009D9CA1 call GetSystemDirectoryA
CODE:009D9CA6 lea eax, [ebp+var_40]
CODE:009D9CA9 mov edx, offset Buffer ; ""
CODE:009D9CAE mov ecx, 100h
CODE:009D9CB3 call System_LStrFromArray ; Delphi 5 Visual Component Library
CODE:009D9CB8 mov edx, [ebp+var_40]
CODE:009D9CBB mov eax, offset dword_9E23A0
CODE:009D9CC0 mov ecx, offset sz_dzip32 ; '\dzip32.dll'
CODE:009D9CC5 call @@LStrCat3 ; procedure _LStrCat3{var dest:AnsiString; source1: AnsiString; source2: AnsiString};
CODE:009D9CCA mov eax, ds:dword_9E23A0
CODE:009D9CCF call System_LStrToPChar ; /*
CODE:009D9CCF ; * function LStrToPChar(const s: AnsiString): PChar
CODE:009D9CCF ; * 把String类型转换为char *类型
CODE:009D9CCF ; */
CODE:009D9CD4 push eax ; lpLibFileName
CODE:009D9CD5 call LoadLibraryA
CODE:009D9CDA mov ebx, eax
CODE:009D9CDC test ebx, ebx
CODE:009D9CDE jbe loc_9D9D64
CODE:009D9CE4 push offset aDzip ; "dzip"
CODE:009D9CE9 push ebx ; hModule
CODE:009D9CEA call GetProcAddress_0
CODE:009D9CEF mov ds:off_9E23A4, eax
CODE:009D9CF4 push offset aDzipvb ; "dzipVB"
CODE:009D9CF9 push ebx ; hModule
CODE:009D9CFA call GetProcAddress_0
CODE:009D9CFF mov ds:off_9E23A8, eax
CODE:009D9D04 push offset aGetzipexternal ; "getZipExternalCancel"
CODE:009D9D09 push ebx ; hModule
CODE:009D9D0A call GetProcAddress_0
CODE:009D9D0F mov ds:off_9E23AC, eax
CODE:009D9D14 push offset aGetzipprogtitl ; "getZipProgTitle"
CODE:009D9D19 push ebx ; hModule
CODE:009D9D1A call GetProcAddress_0
CODE:009D9D1F mov ds:off_9E23B0, eax
CODE:009D9D24 push offset aRegisterextern ; "registerExternZipProg"
CODE:009D9D29 push ebx ; hModule
CODE:009D9D2A call GetProcAddress_0
CODE:009D9D2F mov ds:off_9E23B4, eax
CODE:009D9D34 push offset aResetzipprogti ; "resetZipProgTitle"
CODE:009D9D39 push ebx ; hModule
CODE:009D9D3A call GetProcAddress_0
CODE:009D9D3F mov ds:off_9E23B8, eax
CODE:009D9D44 push offset aSetzipexternal ; "setZipExternalCancel"
CODE:009D9D49 push ebx ; hModule
CODE:009D9D4A call GetProcAddress_0
CODE:009D9D4F mov ds:off_9E23BC, eax
CODE:009D9D54 push offset aSetzipprogtitl ; "setZipProgTitle"
CODE:009D9D59 push ebx ; hModule
CODE:009D9D5A call GetProcAddress_0
CODE:009D9D5F mov ds:off_9E23C0, eax
*****************************Dll 劫持篇华丽分割线******************************************************************
*****************************检测虚拟机篇 华丽分割线****************************************************************
2. 检测虚拟机篇
1. 该dzip32.dll会检测当前的环境是否运行于虚拟机,当运行于虚拟机则会提示:不允许运行于虚拟机,并自动退出该木马.
2. 检测虚拟机的函数为CheckVMWare(),函数名称为INightElf自定义命名的
3. 该检测虚拟机函数的理论基础为:
一些虚拟化平台包含后门式的通信通道,以方便虚拟机与主机软件之间的通信.例如,下面的4行代码可以确定软件是否在一个VMware虚拟机中运行
Mov eax,0x564D5868 ;VMXh
Mov ecx,10
Xor ebx,ebx
Mov dx,0x5658;’VX’
In eax,dx
如果程序在虚拟机中,这段代码将导致EBX 寄存器包含0x564D5868这个值;如果不在虚拟机中,这段代码将造成一个异常,或者不会改变EBX的寄存器.这段指令序列利用了一个机制:即用户空间程序通常不允许使用X86 中的in 指令.但是在VMware 中,这个指令序列可以检测一个特殊的通信通道.VMware Tools 就是利用这个通道与主机进行数据交换,(如剪贴板内容)
4.下面是dzip32.dll 汇编代码
CODE:009D8684 ; /*
CODE:009D8684 ; * 参数描述:检测程序是否运行在虚拟机上
CODE:009D8684 ; * 但运行于虚拟机,返回值为1
CODE:009D8684 ; * 非运行于虚拟机,返回值为0
CODE:009D8684 ; */
CODE:009D8684 ; BOOL CheckVMWare();
CODE:009D8684 ; Attributes: bp-based frame
CODE:009D8684
CODE:009D8684 CheckVMWare proc near ; CODE XREF: TForm1_FormCreate+2C p
CODE:009D8684 ; DllEntryPoint:loc_9D9D64 p
CODE:009D8684
CODE:009D8684 var_4 = dword ptr -4
CODE:009D8684
CODE:009D8684 push ebp
CODE:009D8685 mov ebp, esp
CODE:009D8687 push ecx
CODE:009D8688 push ebx
CODE:009D8689 push esi
CODE:009D868A push edi
CODE:009D868B xor eax, eax
CODE:009D868D
CODE:009D868D loc_9D868D:
CODE:009D868D mov [ebp+var_4], eax
CODE:009D8690 xor eax, eax
CODE:009D8692 push ebp
CODE:009D8693 push offset ExceptionHandle
CODE:009D8698 push dword ptr fs:[eax]
CODE:009D869B mov fs:[eax], esp
CODE:009D869E mov eax, 564D5868h
CODE:009D86A3 mov ebx, 0
CODE:009D86A8 mov ecx, 0Ah
CODE:009D86AD mov edx, 5658h
CODE:009D86B2 in eax, dx ; 当前运行环境为虚拟机则 EBX = 564D5868h.否则为异常
CODE:009D86B3 cmp ebx, 564D5868h
CODE:009D86B9 jnz short loc_9D86C2
CODE:009D86BB mov [ebp+var_4], 1
CODE:009D86C2
CODE:009D86C2 loc_9D86C2: ; CODE XREF: CheckVMWare+35 j
CODE:009D86C2 xor eax, eax
CODE:009D86C4 pop edx
CODE:009D86C5 pop ecx
CODE:009D86C6 pop ecx
CODE:009D86C7 mov fs:[eax], edx
CODE:009D86CA jmp short loc_9D86DB
CODE:009D86CC ; ---------------------------------------------------------------------------
CODE:009D86CC
CODE:009D86CC ExceptionHandle: ; DATA XREF: CheckVMWare+F o
CODE:009D86CC jmp ExceptionFun
CODE:009D86D1 ; ---------------------------------------------------------------------------
CODE:009D86D1 xor eax, eax
CODE:009D86D3 mov [ebp+var_4], eax
CODE:009D86D6 call System_DoneExcept
CODE:009D86DB
CODE:009D86DB loc_9D86DB: ; CODE XREF: CheckVMWare+46 j
CODE:009D86DB mov eax, [ebp+var_4]
CODE:009D86DE pop edi
CODE:009D86DF pop esi
CODE:009D86E0 pop ebx
CODE:009D86E1 pop ecx
CODE:009D86E2 pop ebp
CODE:009D86E3 retn
CODE:009D86E3 CheckVMWare endp
***************************3.StartUpInfo反加载篇华丽 分割线*******************************************
3. GetStartupInfo 反加载篇
1.Windows 加载器创建进程的时候会把StartUpInfo 的结构值设为0,而一般的可执行文件加载器创建进程的时候,则不会把StartUpInfo结构清0,利用OD来启动进程时,该结构不为0,StartUpInfo的结构如下
typedef struct _STARTUPINFO {
DWORD cb;
LPTSTR lpReserved;
LPTSTR lpDesktop;
LPTSTR lpTitle;
DWORD dwX;
DWORD dwY;
DWORD dwXSize;
DWORD dwYSize;
DWORD dwXCountChars;
DWORD dwYCountChars;
DWORD dwFillAttribute;
DWORD dwFlags;
WORD wShowWindow;
WORD cbReserved2;
LPBYTE lpReserved2;
HANDLE hStdInput;
HANDLE hStdOutput;
HANDLE hStdError;
} STARTUPINFO,
*LPSTARTUPINFO;
2. dzip32.dll 利用该方法来检测当前程序是否是被调试程序启动
CODE:009D98EC ; /*
CODE:009D98EC ; * 判断当前程序是否处于调试中
CODE:009D98EC ; * 当处于调试之中,返回值为1
CODE:009D98EC ; * 当为正常情况,返回值为0
CODE:009D98EC ; */
CODE:009D98EC
CODE:009D98EC CheckDebug_DllEntry proc near ; CODE XREF: DllEntryPoint+10D p
CODE:009D98EC
CODE:009D98EC var_34 = dword ptr -34h
CODE:009D98EC var_30 = dword ptr -30h
CODE:009D98EC var_2C = dword ptr -2Ch
CODE:009D98EC var_28 = dword ptr -28h
CODE:009D98EC var_24 = dword ptr -24h
CODE:009D98EC var_20 = dword ptr -20h
CODE:009D98EC var_1C = dword ptr -1Ch
CODE:009D98EC
CODE:009D98EC add esp, -44h
CODE:009D98EF push esp ; lpStartupInfo
CODE:009D98F0 call GetStartupInfoA_0
CODE:009D98F5 cmp [esp+44h+var_34], 0
CODE:009D98FA jnz short loc_9D9926
CODE:009D98FC cmp [esp+44h+var_30], 0
CODE:009D9901 jnz short loc_9D9926
CODE:009D9903 cmp [esp+44h+var_24], 0
CODE:009D9908 jnz short loc_9D9926
CODE:009D990A cmp [esp+44h+var_20], 0
CODE:009D990F jnz short loc_9D9926
CODE:009D9911 cmp [esp+44h+var_1C], 0
CODE:009D9916 jnz short loc_9D9926
CODE:009D9918 cmp [esp+44h+var_2C], 0
CODE:009D991D jnz short loc_9D9926
CODE:009D991F cmp [esp+44h+var_28], 0
CODE:009D9924 jz short loc_9D992A
CODE:009D9926
CODE:009D9926 loc_9D9926: ; CODE XREF: CheckDebug_DllEntry+E j
CODE:009D9926 ; CheckDebug_DllEntry+15 j
CODE:009D9926 ; CheckDebug_DllEntry+1C j
CODE:009D9926 ; CheckDebug_DllEntry+23 j
CODE:009D9926 ; CheckDebug_DllEntry+2A j
CODE:009D9926 ; CheckDebug_DllEntry+31 j
CODE:009D9926 mov al, 1
CODE:009D9928 jmp short loc_9D992C
CODE:009D992A ; ---------------------------------------------------------------------------
CODE:009D992A
CODE:009D992A loc_9D992A: ; CODE XREF: CheckDebug_DllEntry+38 j
CODE:009D992A xor eax, eax
CODE:009D992C
CODE:009D992C loc_9D992C: ; CODE XREF: CheckDebug_DllEntry+3C j
CODE:009D992C add esp, 44h
CODE:009D992F retn
CODE:009D992F CheckDebug_DllEntry endp
先发布一下rose 流程图,接下来时间遍要写业务分析
1.接下来便要开始分析dzip32.dll 业务处理逻辑的,该dll会跟木马服务端通信,并检测当前的用户是否合法.我的最终目的便是要劫持socket通信,去除用户检测!离线转帐,不需要用户验证,该dll逆向的过程,非常考验INightElf 关于Delphi的反汇编能力,需要知道那些是库函数,那些是用户函数.
该dzip32.dll 衣服被我脱的刚刚干干净净,都不知道为什么我有那么大的毅力和精力来做这件事.哈哈,表扬一下自己
*********************************Delphi 基础反汇编 篇 华丽分割线********************************************************
3. Delphi 基础反汇编 篇
如何开始呢,如何组织呢?感觉有点难度
好吧,那就从一个Delphi 反汇编初学者的角度入手吧.可能有点啰嗦,高手请直接忽视吧.我只是提供一个Delphi 反汇编思路而已.
1. 用IDA 编译这个dzip32.dll,可能是IDA 对Delphi 5反汇编支持并不友好,IDA很难识别库函数,导致你不知道如何分析,那些是库函数,那些是用户自定义函数.例如图1是原始编译,图2是INightElf分析后重新注释的.它并不会把函数__fastcall System::__linkproc__ LStrClr(void *)给分析出来,假如你把System::__linkproc__ LStrClr当作自定义函数分析进去,那你就陷入了困境了.
图1
图2
那怎么办呢?
这个时候,编程的基础知识起了一些重要作用,Delphi一般都会创建窗口,或者创建线程来处理事件.这样就把焦点转化到寻找窗口函数和线程事件了
2. 在IDA的Function Name 列表中,IDA识别不出来窗口函数,不过能识别出Import 函数,由于Delphi 是建立在Windows Api 的基础上面,所以我们要找到创建线程的API 函数, CreateThread然后查看函数调用链,就一定能找到关键的函数.
找到函数sub_60458C调用,继续往上查看sub_61DB6C调用,再往上便是DllEntryPoint 入口函数了,所以从这里可以看出.
非常关键的调用顺序DllEntryPoint --61DB6C --sub_60458C –CreateThread .我们只要分析61DB6C 和sub_60458C这两个函数便缩小了分析的范围
3. INightElf 个人觉得逆向分析与软件编程一样,非常忌讳,还没有设计就开始编码.一定要有自己的逆向思路,不能猫抓死耗子
不过这样分析仍然困难重重,突然想到论坛上面有一个Delphi 逆向神器.能解析出窗口资源和库函数
当当当................................DarkDe 4 登上了舞台,
用DarkDe 4直接反汇编dzip32.dll,保存反汇编结果,查看dzip32.dpr工程文件,
我靠,竟然把0061DB6C 函数识别出来,原来是库函数,省略了太多功夫了,直接重新命名该函数,那么现在的焦点就是查看off_689188地址是什么东西,直接导航进去,看起来有点规律,但是仍然不知道是什么东西.潜意识有可能是Delphi 创建窗口的机制,因为很多真正处理事件的业务都会放到Form 窗口里面进行处理.
dzip32.dpr工程文件
00689736 33C9 xor ecx, ecx
00689738 B201 mov dl, $01
0068973A A188916800 mov eax, dword ptr [$00689188]
* Reference to: Classes.TThread.Create(TThread;boolean;Boolean);
|
0068973F E82844F9FF call 0061DB6C
00689744 33C0 xor eax, eax
00689746 5A pop edx
00689747 59 pop ecx
00689748 59 pop ecx
00689749 648910 mov fs:[eax], edx
4.现在又被卡壳了.因为我是新手第一次反汇编Delphi 代码,我不知道Delphi 创建窗口会调用哪些函数,好吧.那就自己新建一个Delphi 工程试试,我机器上面没有Delphi 5 ,只有Delphi 7 ,用Delphi 7 编译一个工程吧,看看有什么样的结果
有两种反汇编的结果,一种是调用
Application.CreateForm(TForm1, Form1);
Application.Run;
生成的反汇编
CODE:0044DD40 push ebp
CODE:0044DD41 mov ebp, esp
CODE:0044DD43 add esp, 0FFFFFFF0h
CODE:0044DD46 mov eax, offset dword_44DB58
CODE:0044DD4B call @Sysinit@@InitExe$qqrpv ; Sysinit::__linkproc__ InitExe(void *)
CODE:0044DD50 mov eax, ds:off_44EFC0
CODE:0044DD55 mov eax, [eax]
CODE:0044DD57 call sub_44C20C
CODE:0044DD5C mov ecx, ds:off_44F09C
CODE:0044DD62 mov eax, ds:off_44EFC0
CODE:0044DD67 mov eax, [eax]
CODE:0044DD69 mov edx, off_44D94C _cls_Unit1_TForm1
CODE:0044DD6F call Forms::TApplication::CreateForm(System::TMetaClass *,void *)
CODE:0044DD74 mov eax, ds:off_44EFC0
CODE:0044DD79 mov eax, [eax]
CODE:0044DD7B call @Forms@TApplication@Run$qqrv ; Forms::TApplication::Run(void)
CODE:0044DD80 call @System@@Halt0$qqrv ; System::__linkproc__ Halt0(void)
一种是调用 生成的反汇编结果
form2:= TForm2.Create(nil);
form2.show;
xor ecx, ecx
mov dl, 1
mov eax, off_44D7AC ; _cls_Unit2_TForm2
call Forms::TCustomForm::TCustomForm(Classes::TComponent *)
call Forms::TCustomForm::Show(void)
retn
两种方法无一例外都要引用到即将创建的窗口类函数_cls_Unit2_TForm2 和_cls_Unit2_TForm1
创建窗口的函数为
Forms::TApplication::CreateForm(System::TMetaClass *,void *)
和Forms::TCustomForm::TCustomForm(Classes::TComponent *)
现在我们来对比 dzip32.dll 看看是否有相同之处
5.分析Classes.TThread.Create(TThread;boolean;Boolean)函数,可以确定真正的线程函数为offset sub_689220,怎么分析我就不展开了,假如不明白可以email 我
.code:00689188 off_689188 dd offset off_6891D4 ; DATA XREF: DllEntryPoint+156 r
.code:0068918C dd 7 dup(0)
.code:006891A8 dd offset loc_6891DC
.code:006891AC dd 40h
.code:006891B0 dd offset off_616480
.code:006891B4 dd offset sub_6039C4
.code:006891B8 dd offset sub_61DCA4
.code:006891BC dd offset nullsub_16
.code:006891C0 dd offset sub_6039D8
.code:006891C4 dd offset nullsub_17
.code:006891C8 dd offset sub_603714
.code:006891CC dd offset sub_603730
.code:006891D0 dd offset sub_61DC3C
.code:006891D4 off_6891D4 dd offset sub_61DD58 ; DATA XREF: .code:off_689188 o
.code:006891D8 dd offset sub_689220
.code:00689220 sub_689220 proc near ; DATA XREF: .code:006891D8o
.code:00689220 mov eax, ds:off_69006C
.code:00689225 cmp dword ptr [eax], 0
.code:00689228 jnz short locret_689265
.code:0068922A mov eax, ds:off_68FF2C
.code:0068922F mov eax, [eax]
.code:00689231 call sub_65A454
.code:00689236 mov ecx, ds:off_69006C
.code:0068923C mov eax, ds:off_68FF2C
.code:00689241 mov eax, [eax]
.code:00689243 mov edx, off_6877E4
.code:00689249 call sub_65A46C
.code:0068924E mov eax, ds:off_68FF2C
.code:00689253 mov eax, [eax]
.code:00689255 mov byte ptr [eax+5Bh], 0
.code:00689259 mov eax, ds:off_68FF2C
.code:0068925E mov eax, [eax]
.code:00689260 call sub_65A4EC
.code:00689265
.code:00689265 locret_689265: ; CODE XREF: sub_689220+8j
.code:00689265 retn
.code:00689265 sub_689220 endp
5. sub_689220和第一种反汇编结果对比一下,看看有什么相同之处,请详细看.激动人心的时刻到了
sub_689220 第一种反汇编结果
mov ecx, ds:off_69006C mov ecx, ds:off_44F09C
mov eax, ds:off_68FF2C mov eax, ds:off_44EFC0
mov eax, [eax] mov eax, [eax]
mov edx, off_6877E4 mov edx, off_44D94C _cls_Unit1_TForm1
call sub_65A46C call Forms::TApplication::CreateForm(System::TMetaClass *,void *)
mov eax, ds:off_68FF2C
mov eax, [eax]
mov byte ptr [eax+5Bh], 0
mov eax, ds:off_68FF2C mov eax, ds:off_44EFC0
mov eax, [eax] mov eax, [eax]
call sub_65A4EC call @Forms@TApplication@Run$qqrv ; Forms::TApplication::Run(void)
off_6877E4
off_44D94C _cls_Unit1_TForm1
导航off_6877E4 地址进去,跟off_44D94C _cls_Unit1_TForm1 差不多.
而且sub_65A4EC函数和Forms::TApplication::Run(void)内容一模一样
已经可以确定ff_6877E4是一个窗口类了
此时此刻,多令人激动.因为接下去即将是分析Form的内容,而DarkDe 已经完全把窗口的函数反汇编出来.而且 _cls_Unit1_TForm1已经把窗口类的父类函数都标记出来,那么off_6877E4 窗口类也同样可以参照其标记出来 终于踏上了光明大道了.这一步实在是太重要了.非常关键的一步
接下来便是确定ff_6877E4是那个窗口类,
DarkDe 反汇编出来有5个窗口类
各位新手可以按照我的思路练练手,提高自己的反汇编分析能力.
今天分析就到此为止,请各位看官给点掌声吧.
看雪论坛,基本是只看不回复的.哈哈.
这个dzip32.dll 去年就已经完全逆向出来了,这几天只是觉得不把它拿出来,让它烂在电脑里面,有点对不起我的付出.因为随着时间的推移,我可能没有精力,也没有兴趣去做这件事情,这个月打算辞职换工作,打算往软件上层的方向发展,往项目经理的方向.
但是我一定会把dzip32.dll 逆向的过程完全发表出来,也做为一段疯狂的日子的见证.其实写这篇文章,是非常耗费精力和时间的,你破解的时候思维可以跳跃得很大,但是写文章就不可以了.
欲知后事如何,请听下回分解!
*********************************未完待续**************************************************************
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!