标签:
其实我一开始是冲着这个去了,一个神秘的CORE组织不知道为何物,好像很厉害的样子促就我想把他弄出来。软件是加壳的,这个没什么好讲的,开始就是pushad,于是在栈上下访问断点立马就能拿到magic jmp
然后下断,发现非常容易的断在了messagebox这个函数上,在栈区回溯到检查参数的上一层函数中,我决定写出注册机或者还原原码。于是这么愉快的跟自己决定了
从下午到晚上,我逐字字行慢慢来于是有了如下成果
1 // TEXme01Keygen.cpp : Defines the entry point for the console application. 2 // 3 4 #include "stdafx.h" 5 #include <iostream> 6 #include "windows.h" 7 int _tmain(int argc, _TCHAR* argv[]) 8 { 9 char upstr[150] = "mystrupggg"; 10 char *downstr="mystrdown"; 11 char *symupstr = upstr; 12 symupstr = symupstr + strlen(upstr) + 1; 13 unsigned int m1 = 0xffffffff; 14 m1 = m1 - strlen(upstr)-1; 15 m1 = ~m1; 16 symupstr = symupstr - m1; 17 int m2 = m1 >> 2; 18 char sth[125]; 19 char *symsth = sth; 20 memcpy(sth, symupstr, m2*4); 21 symupstr += m2 * 4; 22 symsth += m2 * 4; 23 int m3 = m1 & 3; 24 memcpy(sth, symupstr, m3 * 4); 25 symupstr += m3 * 4; 26 symsth += m3 * 4; 27 28 char *c1 = sth; 29 char *c2 = sth + strlen(sth) - 1; 30 for (; c1 >= c2; c1++, c2--) 31 { 32 char cc1 = *c1; 33 char cc2 = *c2; 34 *c1 = cc2; 35 *c2 = cc1; 36 } 37 38 39 symsth = sth; 40 symsth = symsth + strlen(sth) + 1; 41 unsigned int n1 = 0xffffffff; 42 n1 = n1 - strlen(upstr) - 1; 43 n1 = ~n1; 44 symsth =symsth- n1; 45 symupstr = upstr+strlen(upstr); 46 int n2 = n1 >> 2; 47 memcpy(symupstr, symsth, n2*4); 48 symupstr += n2 * 4; 49 symsth += n2 * 4; 50 int n3 = n1 & 3; 51 memcpy(symupstr, symsth, n3 * 4); 52 53 char key[] = "SOFTWARE\Microsoft\Windows\CurrentVersion"; 54 PHKEY hKey; 55 RegOpenKeyA(HKEY_LOCAL_MACHINE, key,hKey); 56 char key2[] = "ProductID"; 57 DWORD dwType = REG_SZ; 58 DWORD dwSize; 59 RegQueryValueExA(*hKey, key2, NULL, &dwType, (LPBYTE)sth, &dwSize); 60 symupstr = upstr; 61 symsth = sth; 62 unsigned int x1 = 0xffffffff; 63 x1 = x1 - strlen(upstr) - 1; 64 x1 = ~x1; 65 symsth = symsth + strlen(symsth) + 1; 66 symsth = symsth - x1; 67 int x2 = x1 >> 2; 68 symupstr = symupstr + strlen(upstr); 69 memcpy(symupstr, symsth, x2); 70 symupstr += x2 * 4; 71 symsth += x2 * 4; 72 int x3 = x1 & 3; 73 memcpy(symupstr, symsth, x3); 74 75 76 char key3[] = "RegisteredOwner"; 77 RegQueryValueExA(*hKey, key3, NULL, &dwType, (LPBYTE)sth, &dwSize); 78 symupstr = upstr; 79 symsth = sth; 80 unsigned int y1 = 0xffffffff; 81 y1 = y1 - strlen(upstr) - 1; 82 y1 = ~y1; 83 symsth = upstr + strlen(upstr) + 1; 84 symsth = symsth - y1; 85 int y2 = y1 >> 2; 86 symupstr = symupstr + strlen(upstr); 87 memcpy(symupstr, symsth, y2); 88 symupstr += y2 * 4; 89 symsth += y2 * 4; 90 int y3 = y1 & 3; 91 memcpy(symupstr, symsth, y3); 92 93 unsigned int i1 = 0xffffffff; 94 i1 = i1 - strlen(upstr) - 1; 95 i1 = ~i1; 96 int i2 = i1 - 1; 97 DWORD dw1 = 0x67452301, dw2 = 0xefcdab89, dw3 = 0x98badcfe, dw4 = 0x10325476; 98 int i3 = i2 & 0x3f; 99 int i4 = 0x40; 100 i4 = i4 - i3; 101 *(upstr + strlen(upstr)) = 0x80; 102 if (i4 <= 7) 103 i4 += 0x40; 104 i2 += i4; 105 106 unsigned int j1 = 0xffffffff; 107 j1 = j1 - strlen(upstr) - 1; 108 j1 = ~j1; 109 int j2 = j1 - 1; 110 int j3 = j2 >> 3; 111 if (i2 == 0) 112 { 113 114 } 115 else 116 { 117 118 } 119 }
当然这个是不完整的,因为在最后关头,我发现他跳进了一个函数,而那个函数,嗯。比较大,自己形容呢,就跟一大汉堡似的却没有一点吃的欲望
这张图还是贴出来
五星你应得的,作者你很绝,你可知道多少逆向工作者跪在这下面。。。
当然了如果是爆破的话很快结束了,注册机,我只能呵呵了。水平暂时有限制,但是,只是时间问题不是?我擦勒,这难道不就是软件防盗的核心?拖垮逆向人员的耐心?
日了狗日了狗。
总结一下看着汇编写C的伤心处
1.变量名,真的,我不知道应该给他取个什么名字,完全没有意思,我现在才知道调试符号文件用来的干嘛,一把辛酸泪
2.关于汇编运算符与C运算的区别,逻辑移动算术移动,这点我在网上看到好多说法但是大多不一致。最后稍微有点靠谱的就是分为无符号和有符号
3.记不住地址,这是个最要命的事,有时候突然一个lea指令能把你的思维完全打乱,因为你完全不知道他传送了哪个变量的首地址,幸好有OL拉过去看看知道是哪个
4.怕跟丢,这不光是写C,也是所有逆向的工作的难处
5.不要尝试还原所有代码,比如这个crackme里面,有一些条件几乎不可能达到,比如输入的字符串长度小于0
6.容易看着看着肚子就饿了
我去不写了,睡觉
标签:
原文地址:http://www.cnblogs.com/distanceblog/p/5277842.html