第一个jz向上为第一部分,要让程序输出 “success”的分析:

输入读取:
- 用户输入学生 ID 和密钥。这些输入通过
sub_3A1041
函数读取,该函数可能是封装了 scanf
或类似功能的自定义函数。
内存分配和键值处理:
- 使用
malloc
分配内存,大小取决于 (var_38 - Block) / 8 * 12
。这个计算涉及到一些变量,可能是基于输入的长度或者类似参数。
- 输入的“键”被读取到分配的内存中。
数据处理和比较:
- 代码执行了一系列的
xor
和 shld
操作。这些操作在内存块中进行,可能是执行某种加密或数据转换。
- 之后,内存区域的内容被与另一部分的内容进行比较。如果所有比较都相等 (
jnz loc_3A7C15
未被执行),则继续执行。
循环处理:
xor
操作在一个循环中重复,这个循环基于一个计算得到的次数进行。循环的次数是 (var_38 - Block) / 8
,同样可能基于输入长度。
成功条件:
- 如果所有
xor
操作后的比较都相等,且没有跳转到 loc_3A7C15
,则会执行到打印 “success” 的代码行。
- 在打印 “success” 之前,还会检查
Block
指针是否非空,这可能是为了确认之前的操作或内存分配是否成功。
推测输入值 “2022141530151” 处理流程:
输入处理:
- 首先,代码提示用户输入学生 ID,假设输入 “2022141530151”。这个 ID 被存储在一个由
lea eax, [ebp+Arglist]
和 push eax
指向的缓冲区内,与格式字符串 "%13s"
一起被 sub_3A1041
使用,这个函数在进行进行字符串的读取。
内存分配:
- 接下来代码进行内存分配,这部分涉及到
var_38
和 Block
这两个变量。具体的大小计算是 (var_38 - Block) / 8 * 12
,然后调用 malloc
。通过查阅源码 ,发现var_38
大小为 0x38
, Block
大小为0x3C
的初始值。这个大小计算可能基于你的输入长度或其他因素。
键值读取:
- 然后程序再次提示输入,这次是输入“键”。这个键值也被读取并存储,用来进行后续的数据比较或加密/解密操作。
数据处理:
- 程序执行一系列的
xor
和 shld
指令,这些可能是对数据进行某种形式的处理。这个处理可能依赖于输入的“键”和“ID”的特定属性。
比较逻辑:
- 处理后的数据被与一些预设值进行比较。所有这些比较都必须成功(即相等),程序流程才会继续向前。
成功输出:
- 如果所有条件满足(即所有比较都通过),程序最终会输出 “success”。
观察到,loc_3A7BB1
对应着success输出,前面有 jz loc_3A7BB1
汇编能够跳转(EFLAGS 寄存器 的 PSW 标志为0则跳转),从此处切入。
Shift + F12查看字符串长度,锁定输入长度为 72 位,此时第一次 jz 之前 al 为 0x1 ,不会跳转到key error。

假设输入 1*72,动调查看

通过以上初步检查与分析,初步判定上述汇编代码为对我的输入进行一系列异或操作,形成密钥,并未涉及密钥的检查部分。
定位到cmp函数,打下断点,通过第一次检查后,第一次每次进行到(F9继续执行)

时,为了通过每轮密钥检查,参考以下部分进行修改(F7单步执行):

将 RSI 中(用户输入的值)修改为其将要比较的对象,即 RCX 中存储的值,每次用此方法进行检查绕过,最后将每次修改的内容(12位)拼接在一起,几位最终的密钥:
第一次:17FB6F0AA3BD
第二次:1EFB6F0AA3BD
第三次:7522B8C906D3
第四次:7C24B5A7CB3F
第五次:7D24B5A7CB3D
第六次:7824B5A7CB3D
即最后的 key 值为:17FB6F0AA3BD1EFB6F0AA3BD7522B8C906D37C24B5A7CB3F7D24B5A7CB3D7824B5A7CB3D
最后,取消所有断点,在打印success代码后打断电,观察结果:

即为答案。
反汇编:
用ida.exe
进入该程序,快捷键F5,查看反汇编代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
| int __cdecl main_0(int argc, const char **argv, const char **envp) { _DWORD *v3; // esi __int64 v4; // rax unsigned int v5; // ebx unsigned int v6; // eax _DWORD *v7; // edx unsigned int v8; // edi int v9; // ecx _DWORD *v10; // eax _DWORD *v11; // eax _DWORD *v12; // eax _DWORD *v13; // eax _BYTE *v14; // edx char v16; // [esp-10h] [ebp-80h] char v17; // [esp-4h] [ebp-74h] char v18; // [esp+0h] [ebp-70h] unsigned int v19; // [esp+10h] [ebp-60h] int v20; // [esp+24h] [ebp-4Ch] int v21; // [esp+28h] [ebp-48h] int v22; // [esp+2Ch] [ebp-44h] int v23; // [esp+30h] [ebp-40h] void *Block; // [esp+34h] [ebp-3Ch] BYREF int v25; // [esp+38h] [ebp-38h] int v26; // [esp+3Ch] [ebp-34h] int Buffer[4]; // [esp+40h] [ebp-30h] BYREF char Arglist[16]; // [esp+50h] [ebp-20h] BYREF int v29; // [esp+6Ch] [ebp-4h]
sub_4010AA(&Block); v29 = 0; sub_401177("input the student id: ", v17); sub_401041("%13s", (char)Arglist); sub_401177("input the key: ", v16); v3 = malloc(12 * ((v25 - (int)Block) >> 3) + 1); sub_401041("%s", (char)v3); if ( !(unsigned __int8)sub_4015BE(v3, 12 * ((v25 - (int)Block) >> 3)) ) goto LABEL_14; v4 = sub_401325(Arglist); v5 = v4; v6 = HIDWORD(v4); v7 = Block; v8 = 0; v19 = v6; if ( (v25 - (int)Block) >> 3 ) { v23 = __PAIR64__(v6, v5) >> 31; v22 = __PAIR64__(v6, v5) >> 30; v21 = __PAIR64__(v6, v5) >> 29; v20 = __PAIR64__(v6, v5) >> 28; v9 = 2 * v5; while ( 1 ) { v7[2 * v8] ^= v5; v7[2 * v8 + 1] ^= v6; v10 = Block; *((_DWORD *)Block + 2 * v8) ^= v9; v10[2 * v8 + 1] ^= v23; v11 = Block; *((_DWORD *)Block + 2 * v8) ^= 4 * v5; v11[2 * v8 + 1] ^= v22; v12 = Block; *((_DWORD *)Block + 2 * v8) ^= 8 * v5; v12[2 * v8 + 1] ^= v21; v13 = Block; *((_DWORD *)Block + 2 * v8) ^= 16 * v5; v13[2 * v8 + 1] ^= v20; sub_4015EB((char *)Buffer, "%012llX\n", *((_DWORD *)Block + 2 * v8)); if ( Buffer[0] != *v3 || Buffer[1] != v3[1] || Buffer[2] != v3[2] ) break; ++v8; v7 = Block; v3 += 3; v9 = 2 * v5; v6 = v19; if ( v8 >= (v25 - (int)Block) >> 3 ) goto LABEL_8; } LABEL_14: sub_401177("key error", v18); exit(0); } LABEL_8: sub_401177("success", v18); v14 = Block; if ( Block ) { if ( ((v26 - (_DWORD)Block) & 0xFFFFFFF8) >= 0x1000 ) { v14 = (_BYTE *)*((_DWORD *)Block - 1); if ( (unsigned int)((_BYTE *)Block - v14 - 4) > 0x1F ) invalid_parameter_noinfo_noreturn(); } sub_4010D7(v14); } return 0; }
|