0x01 非明码比较
实验环境
推荐使用的环境 | 备注 | |
---|---|---|
操作系统 | Windows 10 | |
编译器 | ||
编译选项 | ||
build版本 | ||
调试器 | OD |
实验过程
通过字符串的交叉引用定位到调用MessageBoxA函数之类,随后看其retn的地址时00401232
40134D是成功的MessageBox。
0040137E函数
伪代码翻译:
username is char*;
while(*username){
if *usernmae < 'A'
call errorMessageBox
if *username < 'Z'
username++
else{
*username = *username - 20h
username++
}
k1 = k1 + *username
}
sum = sum^0x5678
4013D8函数
伪代码翻译
while(*authcode)
{
tmp = 0ah
*authcode = *autocode-30h
k2 = k2 * tmp1
m2 = *authcode + k2
authocode++
}
k2 = k2 ^ 1234h
// 其实就是将authcode的数字^1234h
故而注册及算法就是
int(k2)^5678 = authcode
authcode = k1^0x1234^0x5678
书上写的有点省略。
0x02 Nag去除
实验环境
推荐使用的环境 | 备注 | |
---|---|---|
操作系统 | Windows 10 | |
编译器 | ||
编译选项 | ||
build版本 | ||
调试器 | OD |
实验过程
对应显示代码
这里的对话框函数指针是当对话框接收到消息的时候自动调用的函数。
将其对话框函数指针与对话框id换成主对话框就跳过了。
或者直接跳转到显示主对话框的指令处。
0x03拆除KeyFile保护
实验环境
推荐使用的环境 | 备注 | |
---|---|---|
操作系统 | Windows 10 | |
编译器 | ||
编译选项 | ||
build版本 | ||
调试器 | OD |
实验过程
首先通过Process Monitor定位文件名。
然后OD设个条件断点bp CreateFileA,[SRING [eps+4]]=="KwazyWeb.bit"注意这个函数是CreateFileA,所以路径名别带中文,不然建不出来。
然后分析代码
call 401000
这个叫校验函数主要是根据传入的al让坐标从C处进行移动如果移动到X处则验证成功。
伪代码
bool check(){
int len
char* username
char* key
fp = open("key")
read(fp, len, 1) // 第一个字节为第二个数据长度
read(fp, username, len)// 第二次读取username
*username=这一段数据之和
read(fp, key, 12h)//读取18个字节的验证
while(*key){
*key = *key ^ *username
*key++
}
//随后就是跑图了
for(i=0;i<18;i++){
for(j=6;j<0;j=j-2){
tmp = *key >> (j/2)
tmp = tmp & 3
swtch(tmp)
case 0:向上动;break;
case 1:右移动;break;
case 2:下移动;break;
default:左移动;break;
}
}
}
转换成16进制A9 AB A5 10 54 3F 30 55 65 16 56 BE F3 EA E9 50 55 AF
与自己用户名字节加起来的低8位相异或就是所得key
注册代码写的有点丑陋。。太久没用过这个库了
import bitstring
tmp = "A9 AB A5 10 54 3F 30 55 65 16 56 BE F3 EA E9 50 55 AF"
s = "hu1y40"
a = bitstring.BitArray(s.encode("utf-8"))
b = bitstring.BitArray()
res = bitstring.BitArray()
tmp1 = 0
for i in range(0,a.len,8):
tmp1 += a[i:i+8].uint
for i in tmp.split(" "):
b.append("0x"+i)
for i in range(0,b.len,8):
res.append('uint:8='+str(int("0x"+hex(tmp1)[-2:], 16) ^ b[i:i+8].uint))
print(res.hex)
0x04网络验证
实验环境
推荐使用的环境 | 备注 | |
---|---|---|
操作系统 | Windows 10 | |
编译器 | ||
编译选项 | ||
build版本 | ||
调试器 | OD |
实验过程
下面数据区的11字节是加密的数据
获取两个文本后首先执行的代码
这里很明显是一个for循环,练习一下汇编翻译
for(int i=0;i<keyLenth+nameLenth+3;i++){
buf[i] ^= 0xA6
}
数据组成为
(nameLenth,keyLenth,randRes,name,key)其皆与A6异或
for(int i=0;i<revLenth;i++){
ary = revData[i] ^ 0x6E
}
收到了5A个数据
数据范围为68+5A-1=C1
即41AE68~41AEC1
#include<idc.idc>
static main() {
auto ea_from = 0x401000;
auto ea_to = 0x40F951;
auto range1 = 0x41AE68;
auto range2 = 0x0041AEC1;
auto fp = fopen("code.txt", "w");
auto ea = ea_from;
while (ea < ea_to) {
auto cmd = GetMnem(ea);
if (cmd == "mov" || cmd == "lea") {
auto opcode = Dword(NextNotTail(ea) - 4);
if (opcode < 0) {
opcode = ~opcode + 1;
}
Message("-> %08X %08X\n", ea, opcode);
if (range1 <= opcode && opcode <= range2) {
auto delta = opcode - range1;
MakeComm(ea, form("// +0x%04X", delta));
fprintf(fp, "%08X %s\n", ea, GetDisasm(ea));
}
}
ea = NextNotTail(ea);
}
fclose(fp);
Message("OK!");
}
idc脚本
输出
0040113D mov cl, byte_41AEB0; // +0x0048
004016B6 mov byte_41AE68[eax], dl; // +0x0000
004016C0 mov cl, byte_41AE68+4; // +0x0004
004016D0 mov dl, byte_41AE68+0Eh; // +0x000E
004016E7 mov cl, byte_41AE68+0Ah; // +0x000A
004016F7 mov dl, byte_41AE68+23h; // +0x0023
00401707 mov al, byte_41AE68+3Ch; // +0x003C
00401713 mov cl, byte_41AE68+42h; // +0x0042
跳过send和recv函数
将比较的数据写入全局数据区
文章评论