OD破解IDA安装文件

破解版ida提取地址。

完整版在知乎,附有视频文件(被和谐了)。

https://zhuanlan.zhihu.com/p/54989609

链接: https://pan.baidu.com/s/1TtTV-5YB8HwcXsEZ1sZSfg 提取码: f1qr 复制这段内容后打开百度网盘手机App,操作更方便哦

 


 

相信有很多同行在学习编程的时候,总都会用到od,ida,windbg等调试工具,这三款工具都具有强大的调试功能,能帮我们高效快捷地分析代码。虽然大部分调试工具都是免费的,但是ida却不是免费的(当然在各位大佬眼里,用注册码基本上也等于免费了),所以我有一个大胆的想法,能不能利用od来破解ida的安装程序呢?

 

作为一正在个学习中的cracker,破解程序可以说是日常生活的一部分,有时候也会写一些代码自己debug,但是破解商用程序的案例却好像没有。正好前几天下了一个ida安装程序,我看这个程序logo设计太丑,不如就破解了它吧(没错,本人就是华农的学生)。

 

我希望的效果是下面这样的,希望看起来程序就像没动过手脚一样(不新增节,不注入dll),但实际上已经完成了破解(就像那种挥一挥衣袖,不带走一片云彩)。

 

我们希望点击下一步安装的时候可以绕过注册码校验这一步,如下图:

 

 

老规矩,先上od,然而无法断点,我们f9运行之后,弹窗出来之后f12,并没有出现我们想要的结果,此时程序继续运行,有没有双手挠头的既视感。这样子的结果确实挺皮的,无法下断点还真不好办,只能重新载入“ctrl+f8”单步调试了。单步调试结果如下,还是发现了一些线索。

 

堆栈图:

0012FE78   00409A61  /CALL 到 CreateProcessA 来自 idapronw.00409A5C
0012FE7C   00000000  |ModuleFileName = NULL
0012FE80   0043255C  |CommandLine = ""C:\Users\zhuhelin\AppData\Local\Temp\is-T5JDE.tmp\idapronw_hexx86w_hexarmw_140604_8e881c7073422b06ad99444a1b085e32.tmp" /SL5="$1301F2,150750097,53248,C:\Users\zhuhelin\Desktop\idapronw_hexx86w_hexarmw_140604_8e881c7073422b06ad9"...
0012FE84   00000000  |pProcessSecurity = NULL
0012FE88   00000000  |pThreadSecurity = NULL
0012FE8C   00000000  |InheritHandles = FALSE
0012FE90   00000000  |CreationFlags = 0
0012FE94   00000000  |pEnvironment = NULL
0012FE98   00000000  |CurrentDir = NULL
0012FE9C   0012FECC  |pStartupInfo = 0012FECC
0012FEA0   0012FEBC  \pProcessInfo = 0012FEBC

 

我们可以发现,安装程序实际上是调用了另外一个进程来进行安装的,而且是调用的临时文件夹的“.tmp”临时文件安装的。那好办,知道了这个,我们直接附加调试不就完了吗。

 

通过附加调试我们成功绕过了注册码验证,但是问题也来了,实际调用的".tmp"安装文件每次都是在不同的文件夹里面,我们不可能每次安装都手动破解,这样多麻烦。所以如果我们能让安装文件放在固定的文件夹里面,那样不就可以一劳永逸地解决问题了吗?因此,我们只需要把我们修改过的".tmp"文件放在固定的文件夹,修改传给CreateProcessA的参数,把修改过的".tmp"传给CreateProcessA,不就解决问题了吗。

 

0040AB9C      E8 BF010000   call idapronw.0040AD60           //原地址 call 004099ec



0040AD60      B8 70AD4000   mov eax,idapronw.0040AD70                ;  ASCII "idapronw_hexx86w_hexarmw_140604_8e881c7073422b06ad99444a1b085e32.tmp"
0040AD65    ^ E9 82ECFFFF   jmp idapronw.004099EC            //返回原先地址
0040AD6A      00            db 00
0040AD6B      00            db 00
0040AD6C      00            db 00
0040AD6D      00            db 00
0040AD6E      00            db 00
0040AD6F      00            db 00
0040AD70   .  69 64 61 70 7>ascii "idapronw_hexx86w"
0040AD80   .  5F 68 65 78 6>ascii "_hexarmw_140604_"
0040AD90   .  38 65 38 38 3>ascii "8e881c7073422b06"
0040ADA0   .  61 64 39 39 3>ascii "ad99444a1b085e32"
0040ADB0   .  2E 74 6D 70 0>ascii ".tmp",0

 

修改函数调用处的地址,跳转到我们添加的代码的地址,将eax改为我们保存修改后的".tmp"安装文件的地址,再跳转回原地址。只可惜然并卵,并没有任何奇迹发生。所以我猜测在CreateProcessA之前可以有某些函数要对这个地址进行校验,那这次我们直接在CreateProcessA入栈之前修改eax,如下图00409A54:

 

00409A40  |.  50            push eax                                 ; /pProcessInfo = 0012FEBC
00409A41  |.  8D45 B8       lea eax,[local.18]                       ; |
00409A44  |.  50            push eax                                 ; |pStartupInfo = 0012FEBC
00409A45  |.  6A 00         push 0x0                                 ; |CurrentDir = NULL
00409A47  |.  6A 00         push 0x0                                 ; |pEnvironment = NULL
00409A49  |.  6A 00         push 0x0                                 ; |CreationFlags = 0
00409A4B  |.  6A 00         push 0x0                                 ; |InheritHandles = FALSE
00409A4D  |.  6A 00         push 0x0                                 ; |pThreadSecurity = NULL
00409A4F  |.  6A 00         push 0x0                                 ; |pProcessSecurity = NULL
00409A51  |.  8B45 FC       mov eax,[local.1]                        ; |
00409A54      B8 60AD4000   mov eax,idapronw.0040AD60 //原指令call 00403414
00409A59  |.  50            push eax                                 ; |CommandLine = "?@"
00409A5A  |.  6A 00         push 0x0                                 ; |ModuleFileName = NULL
00409A5C  |.  E8 7BA9FFFF   call <jmp.&kernel32.CreateProcessA>      ; \CreateProcessA

 

这次确实有反应了,但是却是这样的,你可以试一下把".tmp"文件的后缀改为".exe",双击后也是这样的。换句话说,通过这样创建的进程并没有和主进程建立通信,这也是一个行不通的方法。

 

 

到目前为止,通过调用破解过的".tmp"文件这个思路看来是行不通了,主进程和调用进程之间应该存在某种验证方式,所以我们现在只能在CreateProcessA调用之前修改eax(临时文件夹地址)地址中的文件了,也即是之前视频中写入的5个nop。我们目前能够选择修改的方法有三种:其一是远程代码注入(这是一种骚操作,不推荐);其二是dll'注入和apihook(这种也算了,一看就是破解版,咱们的目的是起码要让破解版看起来像是a或,加一个dll这种操作看起来就像掉线头了,所以也不推荐);还剩下一种就是在原先程序领空的基础上手动添加代码修改(也是我用的修改办法)。

 

在原程序领空的基础上直接修改,你需要有个条件,那就是原程序调用了类似"loadlibrary"或者"GetProcAddress"这类函数,所幸的是该程序两个函数都调用了。

 

00407043  |.  68 3C714000   push idapronw.0040713C                   ; /ProcNameOrOrdinal = "GetUserDefaultUILanguage"
00407048  |.  68 58714000   push idapronw.00407158                   ; |/pModule = "kernel32.dll"
0040704D  |.  E8 0AD4FFFF   call <jmp.&kernel32.GetModuleHandleA>    ; |\GetModuleHandleA
00407052  |.  50            push eax                                 ; |hModule = 77120000 (gdi32)
00407053  |.  E8 0CD4FFFF   call <jmp.&kernel32.GetProcAddress>      ; \GetProcAddress

 

我没认真跟踪调用这个函数的原函数时干嘛的,直接修改je指令跳过它了,并不影响程序运行。

 

0040958C  |.  2C 01         sub al,0x1                               ;  Switch (cases 0..1)
0040958E  |.  72 04         jb short idapronw.00409594     //修改为 jmp 0040959d,跳过
00409590  |.  74 0B         je short idapronw.0040959D     //00409594
00409592  |.  EB 12         jmp short idapronw.004095A6
00409594  |>  E8 8BDAFFFF   call idapronw.00407024         //该指令跳转至GetProcAddress

 

回到之前0040ad60处的地址空间,通过winhex我们发现这里有一大片空白空间,所以我们打算把代码写到这一空间(0040ad30-0040ae00),如下:

 

0040AB9C      E8 BF010000   call idapronw.0040AD32     //首先,还是修改0040ab9c处的跳转命令

                    
0040AD32   $  50            push eax                   //调用 CreateFileA                        
0040AD33   .  53            push ebx
0040AD34   .  51            push ecx                                
0040AD35   .  52            push edx                   //保护现场,后面还要恢复 

0040AD36   .  6A 00         push 0x0
0040AD38   .  6A 00         push 0x0
0040AD3A   .  6A 03         push 0x3
0040AD3C   .  6A 00         push 0x0
0040AD3E   .  6A 03         push 0x3
0040AD40   .  68 000000C0   push 0xC0000000
0040AD45   .  50            push eax                    //CreateFileA参数入栈           
0040AD46   .  68 5AAD4000   push idapronw.0040AD5A
0040AD4B   .  68 D0AD4000   push idapronw.0040ADD0                   ;  ASCII "CreateFileA"
0040AD50   .  68 C0AD4000   push idapronw.0040ADC0                   ;  ASCII "kernel32.dll"
0040AD55   .^ E9 F3C2FFFF   jmp idapronw.0040704D       //获取CreateFileA地址   
0040AD5A   .  FFD0          call eax                    //调用CreateFileA            
0040AD5C   .  50            push eax                    //hfile入栈两次             
0040AD5D   .  50            push eax                    //后面要用两次             

0040AD5E   .  90            nop
0040AD5F   .  90            nop
0040AD60   .  90            nop
0040AD61   .  90            nop
0040AD62   .  90            nop
0040AD63   .  90            nop
0040AD64   .  90            nop
0040AD65   .  90            nop
0040AD66   .  6A 00         push 0x0                     //调用 SetFilePointer 
0040AD68   .  6A 00         push 0x0
0040AD6A   .  68 99AF0600   push 0x6AF99
0040AD6F   .  50            push eax                                 
0040AD70   .  90            nop
0040AD71   .  68 85AD4000   push idapronw.0040AD85
0040AD76   .  68 E0AD4000   push idapronw.0040ADE0                   ;  ASCII "SetFilePointer"
0040AD7B   .  68 C0AD4000   push idapronw.0040ADC0                   ;  ASCII "kernel32.dll"
0040AD80   .^ E9 C8C2FFFF   jmp idapronw.0040704D
0040AD85   .  FFD0          call eax                                 
0040AD87   .  EB 08         jmp short idapronw.0040AD91



0040AD91   > \58            pop eax                       //取出之前入栈的hfile           
0040AD92   .  6A 00         push 0x0
0040AD94   .  68 80AE4000   push idapronw.0040AE80        //5个0
0040AD99   .  6A 05         push 0x5
0040AD9B   .  68 89AD4000   push idapronw.0040AD89        //5个0x90(nop) 
0040ADA0   .  50            push eax                                 
0040ADA1   .  68 B5AD4000   push idapronw.0040ADB5
0040ADA6   .  68 F0AD4000   push idapronw.0040ADF0                   ;  ASCII "WriteFile"
0040ADAB   .  68 C0AD4000   push idapronw.0040ADC0                   ;  ASCII "kernel32.dll"
0040ADB0   .^ E9 98C2FFFF   jmp idapronw.0040704D
0040ADB5      FFD0          call eax                                 ;  call eax
0040ADB7    ^\E9 9EC2FFFF   jmp idapronw.0040705A          //后面空间是数据区,closehandle函数在  
                                                           //另一个区域

//GetProcAddress处理函数
00407043      68 24704000   push idapronw.00407024                   ;  ASCII "CloseHandle"
00407048   .  68 C0AD4000   push idapronw.0040ADC0                   ; /pModule = "kernel32.dll"
0040704D   >  E8 0AD4FFFF   call <jmp.&kernel32.GetModuleHandleA>    ; |\GetModuleHandleA
00407052   .  50            push eax                                 ; |hModule = 00000001
00407053   .  E8 0CD4FFFF   call <jmp.&kernel32.GetProcAddress>      ; \GetProcAddress
00407058   .  C3            retn


0040705A      68 61704000   push idapronw.00407061         //CloseHandle处理函数,因为修改过
0040705F    ^ EB E2         jmp short idapronw.00407043    //GetProcAddress,不用提前入栈
00407061      90            nop
00407062      90            nop
00407063   .  FFD0          call eax                                 
00407065   .  5A            pop edx                                 
00407066   .  59            pop ecx                                  
00407067   .  5B            pop ebx                            
00407068   .  58            pop eax                                  
00407069   .  E9 7E290000   jmp idapronw.004099EC



数据区

00407024  43 6C 6F 73 65 48 61 6E 64 6C 65 00              CloseHandle.

0040ADC0  6B 65 72 6E 65 6C 33 32 2E 64 6C 6C 00 00 00 00  kernel32.dll....
0040ADD0  43 72 65 61 74 65 46 69 6C 65 41 00 00 00 00 00  CreateFileA.....
0040ADE0  53 65 74 46 69 6C 65 50 6F 69 6E 74 65 72 00 00  SetFilePointer..
0040ADF0  57 72 69 74 65 46 69 6C 65 00 00 00 00 00 00 00  WriteFile.......

 

修改完代码之后还要注意一点,那就是修改节属性。

因为我调用的WriteFile的lpNumberOfBytesWritten地址是0040AE80,这个地址不可写的。

 

BOOL WriteFile(
HANDLE  hFile,//文件句柄
LPCVOID lpBuffer,//数据缓存区指针
DWORD   nNumberOfBytesToWrite,//你要写的字节数
LPDWORD lpNumberOfBytesWritten,//用于保存实际写入字节数的存储区域的指针
LPOVERLAPPED lpOverlapped//OVERLAPPED结构体指针
);

 

打开lordpe,PE Editer->Sections->[右键]edit section header,把Flags:60000020H|80000000H,得到E0000020H,让该节(.CODE)可写。

 

 

保存文件,双击运行,程序完全破解。

总的来说,这个程序还是挺有意思的,overlay的壳,双进程保护,利用临时文件夹保存安装程序,要破解还是需要点时间的。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值