继续尝试160个crackme 这次分析算法的过程比较蛋疼,基本上将汇编全部转换成对应功能的c代码了 先试试软件,发现注册的按钮是不可点击的, 估计是检测输入, 正确后才能点击,不管它了,od开搞吧 首先od载入, 提示是个加壳的文件,PEiD查壳显示壳为ASPack 1.08.03 -> Alexey Solodovnikov 比较简单的壳, 手动脱之(具体过程略过不说),od重新加载脱壳后的文件,因为主要讲注册码的算法,所以怎么找到算法的call就不多说了(其实就是我表达能力不行) 截图的注释算是很详细吧 呃, 看了截图突然发现不知道说啥了, 图上都说明了, 那就不说吧 渣渣注册机源码, 就不要吐槽了 #include <iostream> #include <string> using namespace std; int main() { string tmpName = ""; std::cout << "input your name: "; cin >> tmpName; unsigned char pwd[9] = { 0 }; unsigned int a1 = 0x44414D4E; int len1 = tmpName.length() - 1; int a2 = 0; for (unsigned int i = 0; i <= len1; i++) { a2 += tmpName[i]; a1 = (a1 << (32 - 1)) | (a1 >> 1); a1 = (a1 << (32 - i)) | (a1 >> i); a1 ^= a2; } a1 |= 0x10101010; for (unsigned int i = 0; i < 0x4; i++) { a1 = (a1 >> (32 - 0x8)) | (a1 << 0x8); int a3 = a1 & 0xff; *((char*)(&a2)) = a3; a3 &= 0x0f; *((char*)(&a2)) >>= 4; *((char*)(&a2)) &= 0x0f; int AF = 0; if (a3 < 0x0a) { *((char*)(&a3)) = (0xff + *((char*)(&a3)) - 0x69); AF = 1; } else { *((char*)(&a3)) = *((char*)(&a3)) - 0x69; } int tmp = a3 & 0x0f; if (tmp > 9 || AF == 1) { *((char*)(&a3)) -= 6; } if (a3 > 9) { *((char*)(&a3)) -= 0x60; } pwd[i*2 + 1] = a3; a3 = a2 & 0x0f; AF = 0; if (a3 < 0x0a) { *((char*)(&a3)) = (0xff + *((char*)(&a3)) - 0x69); AF = 1; } else { *((char*)(&a3)) = *((char*)(&a3)) - 0x69; } tmp = a3 & 0x0f; if (tmp > 9 || AF == 1) { *((char*)(&a3)) -= 6; } if (a3 > 9) { *((char*)(&a3)) -= 0x60; } pwd[i*2] = a3; } std::cout << "you password: " << pwd << std::endl; system("pause"); return 0; } cracme文件: crackme.zip
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)