170927 逆向-Reversing.kr(Position)
来源:互联网 发布:淘宝文胸模特赵小姐 编辑:程序博客网 时间:2024/06/08 09:06
1625-5 王子昂 总结《2017年9月27日》 【连续第360天总结】
A. Reversing.kr-Position
B.
Position
惯例先查壳
读Readme可以知道是一个检查Name-Serial的程序,我们需要找到对应Serial为”76876-77776”的Name
由于是个GUI程序,只能依靠API或者字符串来定位事件
IDA中没有找到对应的字符串,很是神奇
在OD中搜索却正常能搜索到,于是定位到核心事件函数sub_401740
由于函数太长就不放全部的了,基本上是同一个结构:
ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>(&Name); v1 = 0; v64 = 0; ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>(&Serial); ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>(&v63); LOBYTE(v64) = 2; CWnd::GetWindowTextW(a1 + 304, &Name); // Name if ( *(_DWORD *)(Name - 12) == 4 ) // Name长度为4 { i = 0; while ( (unsigned __int16)ATL::CSimpleStringT<wchar_t,1>::GetAt(&Name, i) >= 0x61u && (unsigned __int16)ATL::CSimpleStringT<wchar_t,1>::GetAt(&Name, i) <= 0x7Au )// 字母 { if ( ++i >= 4 ) // 4个都为字母 {LABEL_8: v5 = 0; while ( 1 ) { if ( v1 != v5 ) { v6 = ATL::CSimpleStringT<wchar_t,1>::GetAt(&Name, v5); if ( (unsigned __int16)ATL::CSimpleStringT<wchar_t,1>::GetAt(&Name, v1) == v6 )// 4个字母各不相同 goto Fail; } if ( ++v5 >= 4 ) { if ( ++v1 < 4 ) goto LABEL_8; // 4个字母各不相同 CWnd::GetWindowTextW(a1 + 420, &Serial); if ( *(_DWORD *)(Serial - 12) != 11 // Serial长度为11 || (unsigned __int16)ATL::CSimpleStringT<wchar_t,1>::GetAt(&Serial, 5) != 45 )// 第六个字符为- { goto Fail; } v7 = ATL::CSimpleStringT<wchar_t,1>::GetAt(&Name, 0); v8 = (v7 & 1) + 5; v59 = ((v7 >> 4) & 1) + 5; v53 = ((v7 >> 1) & 1) + 5; v55 = ((v7 >> 2) & 1) + 5; v57 = ((v7 >> 3) & 1) + 5; v9 = ATL::CSimpleStringT<wchar_t,1>::GetAt(&Name, 1); v45 = (v9 & 1) + 1; v51 = ((v9 >> 4) & 1) + 1; v47 = ((v9 >> 1) & 1) + 1; v10 = ((v9 >> 2) & 1) + 1; v49 = ((v9 >> 3) & 1) + 1; v11 = (wchar_t *)ATL::CSimpleStringT<wchar_t,1>::GetBuffer(&v63); itow_s(v8 + v10, v11, 0xAu, 10); // 将v8+v10放入v11中 v12 = ATL::CSimpleStringT<wchar_t,1>::GetAt(&v63, 0); v13 = ATL::CSimpleStringT<wchar_t,1>::GetAt(&Serial, 0); v2 = &v63; if ( v13 == v12 ) { ATL::CSimpleStringT<wchar_t,1>::ReleaseBuffer(&v63, -1); v14 = (wchar_t *)ATL::CSimpleStringT<wchar_t,1>::GetBuffer(&v63); itow_s(v57 + v49, v14, 0xAu, 10); v15 = ATL::CSimpleStringT<wchar_t,1>::GetAt(&Serial, 1); v16 = ATL::CSimpleStringT<wchar_t,1>::GetAt(&v63, 0); v2 = &v63; if ( v15 == v16 ) {
流程虽然长但是挺简单的:
首先校对Name为4个各不相同的小写字母
然后按顺序取前5位二进制,第1、3个字母的数各+5,2、4个字母的数各+1
然后分别按特定顺序进行相加组合,并校对
第1、2个字母生成前五位,第3、4个字母生成后五位
如abcd
对应的前五位分别为00001, 00010, 00011, 00100
加常数并改变顺序(逆序后将第五位移至第二位)后得到结果
65555, 11211, 65655, 11121
然后按特定顺序相加
65555
11211
→76667
65655
11121
→86766
所以最终的Serial为76667-89766
很容易写出来KeyGen:
f = []for i in range(len(name)): if i%2 : o = 1 else: o = 5 i = ord(s[i]) f0 = [] f0.append((i & 1) + o) f0.append(((i >> 4) & 1) + o) f0.append(((i >> 1) & 1) + o) f0.append(((i >> 2) & 1) + o) f0.append(((i >> 3) & 1) + o) f.append(f0)a=[0, 4, 2, 3, 1]#顺序由IDA中分析得来b=[3, 4, 1, 0, 2]for i in range(5): print(( f[0][a[i]] + f[1][b[i]] ), end='')#前五位print('-', end='')for i in range(5): print(( f[2][a[i]] + f[3][b[i]] ), end='')#后五位
接着考虑逆向,要求Serial为76876-77776
思考了一下这里是按位操作,还有多种可能,没想到什么快捷写脚本的方法,就乖乖数学解题吧
我们知道每个位都经过了a组的+5和b组的+1,所以实际上说明它们的对应位和应该是 10210-11110
这其中特殊的是0和2,意味着对应位分别都是0和都是1;关键在于1是哪个字母带来的
Name到Serial一共经过了3步变换:
1.取前五位ASCII并加常数5/1
2.改变顺序(逆序后将第五位放至第二位)
3.分别取两个字母的特定位置数相加
逐步逆向:
首先知道提示中说了最后一个字母是’p’,Serial和为10210-11110
将p输入正向脚本可以得到12111,即01000
相加的顺序按照b组对应为00100
则能知道另一半的和为11010
按照a组顺序(04231)还原得到10011
将第二位还原至第五位然后逆序,得到01101
则第三个字母的ASCII为0b1101101,即109,即’m’
然后是前两个字母,这次虽然提示,但是由于2和0的特性,可以大大减小可能性:
一共有2个1,即最多出现2x2=4种情况,可以接受
两个数的格式必然为x01y0(两个x中必然一个是1一个是0,y同理)
分别按照a组和b组的顺序还原:
a:
x01y0
x1y00
00y1x
b:
y10x0
y0x01
10x0y
则可能的格式有:
a,b
00010, 10101
00011, 10100
00111, 10000
00100, 10001
写脚本分别输出
flag =[[0b1100010, 0b1110101],[0b1100011, 0b1110100],[0b1100111, 0b1110000],[0b1100100, 0b1110001]]for i in flag: print(chr(i[0])+chr(i[1])+'mp')
bump
ctmp
gpmp
dqmp
第一个是有意义的单词,输入程序验证果然Correct
完成
除了爆破好像没想到什么快速逆向的思路(:з」∠)有大佬做过的话希望能指点一下~
C. 明日计划
Reversing.kr
- 170927 逆向-Reversing.kr(Position)
- 170923 逆向-Reversing.kr(MusicPlayer)
- 170925 逆向-Reversing.kr(Replace)
- 170926 逆向-Reversing.kr(ImagePrc)
- 170928 逆向-Reversing.kr(Direct3D_FPS)
- 170929 逆向-Reversing.kr(Ransomware)
- 170930 逆向-Reversing.kr(Twist)
- 171001 逆向-Reversing.kr(WindowsKernel)
- 171002 逆向-Reversing.kr(AutoHotKey)
- 171003 逆向-Reversing.kr(CSHOP)
- 171010 逆向-Reversing.kr(PEPassword)
- 171011 逆向-Reversing.kr(HateIntel)
- 171013 逆向-Reversing.kr(AutoHotKey2)
- 171014 逆向-Reversing.kr(x64 Lotto)
- 171017 逆向-Reversing.kr(CSharp)
- 171018 逆向-Reversing.kr(Flash Encrypt)
- 171019 逆向-Reversing.kr(MetroApp)
- 171020 逆向-Reversing.kr(Multiplicative)
- MySQL调优和性能分析 -- 学习笔记---- V0.0.1
- java非静态内部类为何不能有静态的成员?
- DLL中的回调函数实现
- maven配置和创建遇到的问题
- CodeForces 864D Make a Permutation! 【贪心】【模拟】
- 170927 逆向-Reversing.kr(Position)
- SSL层
- jdbc获取数据库连接
- java控制台输出各种三角形
- win10 系统 eclipse配置scala+spark开发环境
- 三种简单排序的实现(冒泡排序,选择排序,插入排序 )
- Javascript高级程序设计--第8章笔记---窗口位置
- backbone+requirejs+bootstrap登录注册(maven项目,后台springmvc)
- 反射机制在学习时候的总结