lipss 发表于 2017-4-15 08:13

逆向笔记-逆向XX.exe

本帖最后由 zjh16529 于 2019-6-6 18:28 编辑

##名词注释

System breakpoint:系统断点,OllyDbg用CreateProcessA加载DEBUG_ONLY_THIS_PROCESS参数执行,程序运行之后会触发一个INT13,在系统空间里。

Entry point of main module:主模块的入口点,即文件的入口点。

WinMain:程序的WinMain()函数入口点

OD的设置中-选项-事件中设置




## OD快捷键熟悉

1、F2 下断点,
2、Alt+b 打开断点编辑器,可编辑所有下过的断点
3、空格键 可快速切换断点状态。
4、Ctrl+F9.当位于某个CALL中,这时想返回到调用这个CALL的地方时,可以按“Ctrl+F9”快捷键执行返回功能。这样OD就会停在遇到的第一个返回命令(如RET、RETF或IRET)。
5、Alt+F9 如果跟进系统DLL提供的API函数中,此时想返回到应用程序领空里,可以按快捷键“Alt+F9”执行返回到用户代码命令。
6、Ctrl+G 跳转到API、地址的位置


## 逆向之猜

逆向与开发的知识是成正比关系,只有对开发特别熟悉,逆向一个程序才能猜测到该用哪个关键的API才能快速定位到程序的数据处理。

通过PEID查看程序特征,根据程序语言用IDE生成特征或者熟悉开发的API函数。就可以更方便地让我们定位到获取edit值的函数。






【GetDlgItemText 函数】 用于获取对话框中指定控件的标题或文本。

‘使用OD的快捷键【Ctrl+G】跳转到API的位置下断点。

F2设置断点,当【GetDlgItemTextA】这个函数被调用OD就会中断

【ALT+B】快捷键可以打开断点窗口查看,在断点位置按【空格键】可以激活与禁用断点。






按快捷键【Ctrl+F9】可以回到调用函数的尾部ret处。

## 算法逆向
F7跟进004011E5地址内的函数,进入子程序call 00401340,特别值得注意的是00401359是跳转到4013680的,相关汇编代码注释如下:




加密函数汇编注释如下:
```
00401340push ebp                                 ;ebp入栈
00401341mov ebp,dword ptr ss:         ;将用户名移动到ebp中
00401345push esi                                 ;esi入栈
00401346push edi                                 ;edi入栈
00401347mov edi,dword ptr ss:          ;将参数从堆栈中传给edi(用户名长度值) edi = 5
0040134Bmov ecx,0x3                              ;ecx = 3
00401350xor esi,esi                              ;esi 清 0
00401352xor eax,eax                              ;eax 清0
00401354cmp edi,ecx
00401356jle XTraceMe.00401379                  ;edi<ecx条件成立时跳转,i<len
00401358push ebx
00401359/cmp eax,0x7                           ;比较eax与7的值
0040135Cjle XTraceMe.00401360                  ;当等于7,ZF=1短跳转
0040135E|xor eax,eax
00401360|xor edx,edx                           ;edx清0
00401362|xor ebx,ebx
00401364|mov dl,byte ptr ds:            ;地址低8位的一个字节,dl是存储一个字节的寄存器,ecx = 3, = d
00401367|mov bl,byte ptr ds:       ;004050300C 0A 13 09 0C 0B 0A 08
0040136D|imul edx,ebx                            ;edx * ebx 赋值给 edx, dl为高8位,存储1字节数
00401370|add esi,edx                           ;edx+esi,把值赋予给esi ,esi = 4B0 + 3F2
00401372|inc ecx                                 ;递增指令,ecx 由 3 -> 4 -> 5
00401373|inc eax                                 ;eax = 1,eax++
00401374|cmp ecx,edi
00401376\jl XTraceMe.00401359                  ;ecx 是否大于等于5(用户名长度), jl指令大于不等于满足时跳转
00401378pop ebx
00401379push esi                                 ; /<%ld>
0040137Apush TraceMe.00405078                  ; |Format = "%ld"
0040137Fpush ebp                                 ; |s
00401380call dword ptr ds:[<&USER32.wsprintfA>]; \wsprintfA
00401386mov eax,dword ptr ss:
0040138Aadd esp,0xC
0040138Dpush ebp                                 ; /String2
0040138Epush eax                                 ; |String1
0040138Fcall dword ptr ds:[<&KERNEL32.lstrcmpA>] ; \lstrcmpA
```

程序原先输入的用户名:abcde、序列号:123456。在堆栈窗口看到的是d、e,也就是
```
   name=‘d’,
   name=‘e’
```

根据00401367 地址处判断,密码数组索引第3位之后的值逐位取出与固定地址的值比对。然后在0040137A会输出密钥的值2201。

仔细逆推一遍:

```
   edx =64 * 0C = 4B0

   edx =65 * 0A = 3F2

   4B0 + 3F2=8A2

8A2对应的十进制为2210
```
逆向结论:

abcde转换为十六进制从索引值第3位开始逐位取值,64:d、65:e ,然后与004050300C 0A 13 09 0C 0B 0A 08对应的值进行相乘然后累加。得出的8A2转换成十进制2210就是密码的值。


把加密函数取出来就成了算号注册机,下面是加密函数反汇编转换来的C代码:

```
#include "stdafx.h"
#include <string.h>



//char name = "abcdexxxx";
char name;
char table = { 0xC ,0xA ,0x13 ,0x09 ,0x0C ,0x0B ,0x0A ,0x08 };
int main()
{
      printf(" 输入key:\n ");
      scanf_s("%s",name,65);


      //会用到一个固定地址的值
      //会用到姓名里的后两位
      //eax = i
      int user_len = strlen(name);
      int key_code= 0; //esi



      int count_ecx = 3;//esi
      int eax = 0;      //eax
    for (; count_ecx<user_len;)
      {
                if (eax>7)
                        eax = 0;

                int ebx = 0;
                int edx = 0;

                edx = name;
                ebx = table;
                ebx = edx * ebx;

                key_code += ebx;
                count_ecx++;
                eax++;

      }
      printf("key_code: %d", key_code);
    return 0;
}

```




## 暴力破解

在定位到GetDlgItemText这个API处,F8单步步过向下跟随到有test判断的地方,注意观察数据堆栈区的位置。




汇编指令注释如下:
```
0040119Cmov esi,dword ptr ss:         ;Case 3F5 of switch 0040115E
004011A3mov edi,dword ptr ds:[<&USER32.GetDlgIte>;user32.GetDlgItemTextA
004011A9push ebx
004011AAlea eax,dword ptr ss:
004011AEpush 0x51                              ; /Count = 51 (81.)
004011B0push eax                                 ; |Buffer
004011B1push 0x6E                              ; |ControlID = 6E (110.)
004011B3push esi                                 ; |hWnd
004011B4call edi                                 ; \GetDlgItemTextA
004011B6lea ecx,dword ptr ss:
004011BDpush 0x65                              ; /最大字符数
004011BFpush ecx                                 ; |文本缓冲区指针
004011C0push 0x3E8                               ; |控件标识
004011C5push esi                                 ; |对话框句柄
004011C6mov ebx,eax                              ; |将用户名的长度转到ebx中
004011C8call edi                                 ; \GetDlgItemTextA
004011CAmov al,byte ptr ss:            ;将用户名的第一个字节给al
004011CEtest al,al                               ;检查有没有输入用户名
004011D0je XTraceMe.00401248                     ;如果没有输入用户名跳走,告知输入的字符太少,zf=0跳转
004011D2cmp ebx,0x5
004011D5jl XTraceMe.00401248                     ;如果用户名不大于5那么就跳转到错误提示处
004011D7lea edx,dword ptr ss:          ;用户名地址放到edx中
004011DBpush ebx                                 ;用户名长度
004011DClea eax,dword ptr ss:          ;密码地址放到eax
004011E3push edx                                 ;用户名地址入栈
004011E4push eax                                 ;密码地址入栈
004011E5call TraceMe.00401340                  ;调用函数,相当于a("123456",abcde,5)
004011EAmov edi,dword ptr ds:[<&USER32.GetDlgIte>;user32.GetDlgItem
004011F0add esp,0xC                              ;平衡堆栈
004011F3test eax,eax                           ;函数返回值都是在eax里面的,eax=0注册失败,eax=1注册成功
004011F5nop                                    ;zf标志位为0,满足条件时跳转
```

第一个test指令首先对比用户名是否大于5,不大于5就跳转到弹出错误提示的地方。否则继续执行。F8单步步过进入【GetDlgItemTextA】后面的调用查看相关的代码。004011E5地址处call调用一个函数,并且在之前push了三个参数。




第二处test指令下面那条je跳转指令用nop填充掉。





然后右键【复制到可执行文件】-【所有修改】




选择全部复制




选择【保存文件】,暴力破解就完成了




成功截图







## 样本引用
《加密与解密》这本书里的附带小程序TraceMe.exe。









Jhin 发表于 2017-4-17 15:34

嘿嘿嘿 楼主太厚道 以后会好累的, 现在破个异地登陆的验证都要追回去3次sslv3的计算,以后不造还会累成什么样。 不过说真的, 这程序和fiddler 里面的我用的他们的正版插件真的好像,最后说出来 我的是 success

因素 发表于 2017-4-15 08:37

真不错强力支持啊!{:1_921:}

等待记忆中 发表于 2017-4-15 09:32

谢谢楼主的分享~~~

hcq2ld 发表于 2017-4-15 10:27

虽然看不懂,但要给楼主赞。

皇甫小杰 发表于 2017-4-15 10:30

我也是不懂,还是给楼主点赞

Kay0905 发表于 2017-4-15 10:47

Three_fish 发表于 2017-4-15 11:04

虽然看不懂,但要给楼主赞。

xcz123m 发表于 2017-4-15 14:42

谢谢分享,又学到了。。

纳兰无羁 发表于 2017-4-15 17:16

强大学习学习   感谢楼主

邪梦 发表于 2017-4-15 17:20

学习了,感谢楼主分享,
页: [1] 2 3
查看完整版本: 逆向笔记-逆向XX.exe