1625-5 王子昂 总结《2017年9月25日》 【连续第358天总结】
A. Reversing.kr-Replace
B.

Replace

先查一波壳,还好没有
运行,是一个GUI程序,下面Label框中显示Wrong!,说明没法找Msgbox了呢
随便输入后点Check,就停止运行了……嗯?这么暴力的,输错就GG吗

惯例拖入IDA,WinMain中只有构造窗口的DialogBoxParamA函数,回调函数使用了DialogFunc

搜索字符串发现Correct!在DialogFunc中有引用,遂查看代码并反编译:

// write access to const memory has been detected, the output may be wrong!
BOOL __stdcall DialogFunc(HWND hDlg, UINT a2, WPARAM a3, LPARAM a4)
{BOOL result; // eax@2if ( a2 == 273 ){if ( (unsigned __int16)a3 == 2 ){EndDialog(hDlg, 2);result = 1;}else if ( (unsigned __int16)a3 == 1003 ){input = GetDlgItemInt(hDlg, 1002, 0, 0);sub_40466F();((void (__cdecl *)(void *))loc_404689)(&loc_40469F);*(_DWORD *)sub_40466F = -1013972794;sub_40466F();sub_40466F();*(_DWORD *)sub_40466F = 1768;result = 1;}else{result = 0;}}else{result = 0;}return result;
}

查了一波API手册,发现回调函数其实叫DialogProc,参数说明只能知道a2为指定消息uMsg,a3为指定消息的其他信息wParam

想研究一波前面判断的具体信息,但是没找到相关手册说明uMsg的对应表

内层循环体的GetDlgItemInt很明显就是获取对话框的值
输入了一下试试,发现只能接受数字,字母和符号都是无法输入的

在OD中下断DialogFunc,发现窗口开启状态下会不停地断到,说明消息是不断传送的。似乎是当焦点在窗口上方时a2=273,点击按钮时a3=3。

参数不搞明白倒是不怎么影响啦,在内层循环体下断可以在点击按钮后断到

将输入送入0x4084d0后就call 0040466F了
这个call是一个很关键很有趣的点,需要慢慢地仔细分析
首先回忆一下汇编中函数调用的相关知识
当call某处时,首先将下一条指令的地址压入栈中,然后将EIP改至该行
即相当于
push eip+x ;x是本次指令的长度
jmp n   ;n是函数地址

函数运行完以后执行retn,将栈中之前的地址pop出栈,送入EIP中,继续运行
即相当于
pop eip

下面分析代码

0040466F   $  E8 06000000   call Replace.0040467A
00404674      81            db 81
00404675   .  05 D0844000   add eax,Replace.004084D0
0040467A   .  C705 16604000>mov dword ptr ds:[0x406016],0x619060EB
00404684   .  E8 00000000   call Replace.00404689
00404689  /$  FF05 D0844000 inc dword ptr ds:[0x4084D0]
0040468F  \.  C3            retn
00404690   >  A1 D0844000   mov eax,dword ptr ds:[0x4084D0]
00404695   .  68 9F464000   push Replace.0040469F
0040469A   .  E8 EAFFFFFF   call Replace.00404689
0040469F   .  C705 6F464000>mov dword ptr ds:[0x40466F],0xC39000C6
004046A9   .  E8 C1FFFFFF   call Replace.0040466F
004046AE   .  40            inc eax
004046AF   .  E8 BBFFFFFF   call Replace.0040466F
004046B4   .  C705 6F464000>mov dword ptr ds:[0x40466F],0x6E8
004046BE   .  58            pop eax                                  ;  Replace.00401020
004046BF   .  B8 FFFFFFFF   mov eax,-0x1
004046C4   .^ E9 A8C9FFFF   jmp Replace.00401071

进去就call 40467A
为另外一处赋值以后继续call 404689
在这里为我们的输入+1,然后ret n,即回到刚才call的下一行:404689
于是输入再+1,然后ret n,即回到最外层call的下一行:404674
关键来了,404674是db 81,即未被分析的数字
这里单步执行会发现直接跳到了40467E

也就是说,这一次执行复用了本来的404675处的指令
从机器码可以看出指令内容应该是81 05 D0 84 40 00 C7 05 16 60
于是我就去百度了好久的机器码跟汇编对应指令,也没研究明白……
最后乖乖用自动工具了囧

后面其余的指令没什么意义,再往后执行又同样call了404689,对4084D0+2

即整个call对地址4084D0增加了4+0x601605C7

出来后jmp到了404690

00404690   > \A1 D0844000   mov eax,dword ptr ds:[0x4084D0]
00404695   .  68 9F464000   push Replace.0040469F
0040469A   .  E8 EAFFFFFF   call Replace.00404689
0040469F   .  C705 6F464000>mov dword ptr ds:[0x40466F],0xC39000C6
004046A9   .  E8 C1FFFFFF   call Replace.0040466F
004046AE   .  40            inc eax
004046AF   .  E8 BBFFFFFF   call Replace.0040466F
004046B4   .  C705 6F464000>mov dword ptr ds:[0x40466F],0x6E8
004046BE   .  58            pop eax                                  ;  Replace.00401020
004046BF   .  B8 FFFFFFFF   mov eax,-0x1
004046C4   .^ E9 A8C9FFFF   jmp Replace.00401071

这里把值先送到了eax里
然后push 40469F,这个是为了之后retn准备的,倒是不用在意
call 404689又为4084D0加了一
然后为40466F赋值,再call 40466F

很明显这个call是刚赋值过即更改了指令的,我们跟随过去看一眼:

0040466F   $  C600 90       mov byte ptr ds:[eax],0x90
00404672   ?  C3            retn

对eax指向的内容赋值90

这里很明显就是之前随手输入报错的原因了:eax指向的地址不合法

我们修改一下eax使得它可以继续运行,找一个隔壁空的地址写入eax就可以了
之后程序对eax+1,再次call 40466F。也就是说一次对两个字节的内存写入90

pwn做多了马上就能反应过来\x90是NOP的机器码,也就是说这个call可以抹消两个字节的指令

暂时不知道用处在哪里,我们继续往下运行
还原40466F后jmp 401071:

00401071     /EB 11         jmp short Replace.00401084
00401073     |68 34604000   push Replace.00406034                    ;  Correct!
00401078     |68 E9030000   push 0x3E9                               ; |ControlID = 3E9 (1001.)
0040107D   . |56            push esi                                 ; |hWnd = 004000D0
0040107E   . |FF15 A0504000 call dword ptr ds:[<&USER32.SetDlgItemTe>; \SetDlgItemTextA
00401084   > \B8 01000000   mov eax,0x1
00401089   .  90            nop
0040108A   .  90            nop
0040108B   .  90            nop
0040108C   .  90            nop
0040108D   .  90            nop
0040108E   .  90            nop
0040108F   .  90            nop
00401090   .  5E            pop esi                                  ;  Replace.004000D0
00401091   .  5D            pop ebp
00401092   .  C2 1000       retn 0x10

我们可以看到,Correct的显示是通过SetDlgItemTextA的,现在执行近在咫尺,却又有一个jmp跳过了它。
并且注意OD显示,这个API前方到jmp之间是没有跳转落点的
也就是说,正常执行情况下,最多跳到401071,然后jmp走

那么很明显,要显示Correct,我们就要爆破掉这个jmp
而程序正好自己提供了两个字节的NOP来爆破

也就是说我们只需要计算好地址,使得call 40466F正好抹掉这个jmp就行了

它的地址是00401071,中间的计算是加0x601605CB(注意虽然最后有一个对内存的+1,但是40466F的操作数是eax,所以最终仍然是+4)

加数比得数大,因此需要利用eax的溢出
正好win10的计算器方便的不行,提供了程序员模块,将类型改至DWORD,就得到了结果:

注意输入的是十进制DEC,并且去掉负号哦~

C. 明日计划
Reversing.kr

170925 逆向-Reversing.kr(Replace)相关推荐

  1. 170929 逆向-Reversing.kr(Ransomware)

    1625-5 王子昂 总结<2017年9月29日> [连续第362天总结] A. Reversing.kr-Ransomware B. Ransomware readme提示解密文件,运行 ...

  2. 171019 逆向-Reversing.kr(MetroApp)

    1625-5 王子昂 总结<2017年10月19日> [连续第384天总结] A. reversing.kr B. MetroApp 这次的逆向处理了很多麻烦,学到了不少关于MetroAp ...

  3. 171003 逆向-Reversing.kr(CSHOP)

    1625-5 王子昂 总结<2017年10月3日> [连续第368天总结] A. Reversing.kr-CSHOP B. CSHOP 这次只有一个文件,没有可怕的ReadMe了 打开是 ...

  4. 171002 逆向-Reversing.kr(AutoHotKey)

    1625-5 王子昂 总结<2017年10月2日> [连续第367天总结] A. Reversing.kr-AutoHotKey B. AutoHotKey 解压出来一个ReadMe一个e ...

  5. 171013 逆向-Reversing.kr(AutoHotKey2)

    1625-5 王子昂 总结<2017年10月13日> [连续第378天总结] A. reversing.kr B. AutoHotKey2 解压出来又来了ReadMe 不过这次比较简单,翻 ...

  6. 170926 逆向-Reversing.kr(ImagePrc)

    1625-5 王子昂 总结<2017年9月26日> [连续第359天总结] A. Reversing.kr-ImagePrc B. ImagePrc 首先查壳,运行发现是一个光秃秃的窗口, ...

  7. Reversing.Kr replace题解

    第一次尝试做题,参考了众多大神的讲解,终于把这题解出来了. 我们先运行一下replace.exe,出现下面的框,什么都不输或输错点击check会异外终止.这题估计就是要让Wrong变成correct或 ...

  8. Reversing.kr Replace

    程序运行: 只能输入数字序列,不能输入字母和字符 查壳,无壳,标准c++程序: 我在想,能不能爆破,嘿嘿嘿,但是我不会写相应的脚本. IDA打开,String,找到    "Correct! ...

  9. 【reversing.kr逆向之旅】Position的writeup

    有提示是说flag就是当Serial为76876-77776时的Name    有多解    提示有四位 且最后一位是p ReversingKr KeygenMe Find the Name when ...

最新文章

  1. 彻底取代Redis+数据库架构,京东618稳了!
  2. 日志和告警数据挖掘经验谈——利用日志相似度进行聚类,利用时间进行关联分析...
  3. 5.7.4.framebuffer应用编程实践3
  4. linux系统之我的选择
  5. 抛物线、导弹线轨迹计算
  6. B树插入和删除的各种情况分析
  7. 以太坊ETH不能转账,状态一直是pending状态原因和解决方法
  8. CSS去掉TextBox边框
  9. java目录删除_java删除文件及目录
  10. 三角形~~行列式~~皮克公式~~gcd
  11. bzoj2037 Sue的小球(区间dp,考虑到对未来的贡献)
  12. 邮箱收不到验证邮件怎么回事?为什么我的电子邮件收不到验证码的原因,无限容量邮箱开通
  13. 基于Golang设计一套微服务架构[转]
  14. buff系统 游戏中_arpg游戏的技能系统和buff系统的一种实现
  15. Tagxedo在线云词成像制作工具
  16. java 生僻字 问号_csv导出姓名生僻字变问号
  17. 蛮X搜神记的NetManager分析(1)
  18. 深度学习 图像识别 三
  19. 前端js获取系统更新刷新页面
  20. 基于点击量的趋势分析python_【Python数据科学实战项目】之 基于MovieLens的影评趋势分析详解...

热门文章

  1. 2023年全国DAMA-CDGP数据治理专家认证线上班招生简章
  2. D-017 SWD硬件电路设计
  3. 国产兼容三菱FX3U源码,最新一波bug修改,修改监控时卡顿 问题
  4. 【Apache OFBiz 系列】手把手教你快速运行OFBiz项目
  5. 项目进度管理:控制进度--监控过程组
  6. 数据库之概述模型: 对象模型 + 关系模型
  7. Java云电子病历源码:电子病历在线编辑
  8. mysql msi是什么文件_什么是MSI文件?
  9. 双曲正割matlab求解
  10. 三相电子式导轨电能表ADL400