-
-
[原创]看雪 2016 CTF 第八题 Solution
-
发表于: 2016-11-16 20:42 2997
-
1.第一阶段IDA做静态分析,定位主业务逻辑函数体,其完成的注册码信息加载初始化、用户输入注册码初步处理并进入最终校验。
2.第二阶段Windbg动态调试,验证部分代码性质,结合静态分析得到注册码。
1.静态分析。
(1.1)由下面中文提示信息溯源到主要业务逻辑函数体 sub_140001910,
(该信息在IDA Striing 中为乱码,直接点击跟进)
.rdata:0000000140022008 aVSI db '注册码:',0
(1.2)在下面的 sub_140001910 函数体内
a. Hi_Init_wwA5x5_sub_140001400 加载注册文件,并初始化注册信息二维数组 Hi_wwKeyInfoArray5x5_140025CC0[5][5]。
b. Hi_console_in_fmt_sub_1400012B0 格式化 "%dA%s" 请求用户输入的注册码 KeyMAstr。
c. Hi_get_Mr_for_KeyM_sub_140001300 从用户输入的 KeyMAstr 信息中的 M 获取相应的平方根 Mr。
d. Hi_CheckKeyAstr_with_Mr_sub_1400014B0 检测 KeyMAstr 的 Astr 和 Mr。
//sub_140001910 函数体主要业务逻辑
.text:0000000140001910 ; =============== S U B R O U T I N E =======================================
.text:0000000140001910
.text:0000000140001910
.text:0000000140001910 sub_140001910 proc near ; CODE XREF: sub_140001ADC+11Fp
.text:0000000140001910 ; DATA XREF: .pdata:0000000140026084o
.text:0000000140001910
.text:0000000140001910 var_428_KeyM = dword ptr -428h
.text:0000000140001910 var_418_KeyAstr = byte ptr -418h
.text:0000000140001910 var_18 = qword ptr -18h
.text:0000000140001910
.text:0000000140001910 sub rsp, 448h
.text:0000000140001917 mov rax, cs:__security_cookie
.text:000000014000191E xor rax, rsp
.text:0000000140001921 mov [rsp+448h+var_18], rax
.text:0000000140001929 xor edx, edx
.text:000000014000192B lea rcx, [rsp+448h+var_418_KeyAstr]
.text:0000000140001930 mov r8d, 400h
.text:0000000140001936 call Hi_memset_sub_140002C10 ;
.text:0000000140001936 ; memset(ecx,edx,cbszie:r8)
.text:000000014000193B lea rcx, unk_140021FA0 ;
.text:000000014000193B ; 请将序列号文件存放在程序运行目录下,并命名为names.in 格式参见帖子
.text:000000014000193B ; By 无名侠
.text:0000000140001942 call Hi_Console_out_sub_140001200
.text:0000000140001947 call Hi_Init_wwA5x5_sub_140001400
.text:000000014000194C test al, al
.text:000000014000194E jz short loc_140001995
.text:0000000140001950 lea rcx, aVSI ; "注册码:"
.text:0000000140001957 call Hi_Console_out_sub_140001200
.text:000000014000195C lea r8, [rsp+448h+var_418_KeyAstr]
.text:0000000140001961 lea rdx, [rsp+448h+var_428_KeyM]
.text:0000000140001966 lea rcx, aDaS ; "%dA%s"
.text:000000014000196D call Hi_console_in_fmt_sub_1400012B0
.text:0000000140001972 call Hi_end0_sub_14000A634
.text:0000000140001977 mov ecx, [rsp+448h+var_428_KeyM]
.text:000000014000197B call Hi_get_Mr_for_KeyM_sub_140001300
.text:0000000140001980 test eax, eax
.text:0000000140001982 jnz short loc_1400019AF
.text:0000000140001984 lea rcx, unk_140022018 ;
.text:0000000140001984 ; 注册码有误!
.text:000000014000198B call Hi_Console_out_sub_140001200
.text:0000000140001990 call Hi_end0_sub_14000A634
.text:0000000140001995
.text:0000000140001995 loc_140001995: ; CODE XREF: sub_140001910+3Ej
.text:0000000140001995 xor eax, eax
.text:0000000140001997 mov rcx, [rsp+448h+var_18]
.text:000000014000199F xor rcx, rsp
.text:00000001400019A2 call sub_1400019D0
.text:00000001400019A7 add rsp, 448h
.text:00000001400019AE retn
.text:00000001400019AF
.text:00000001400019AF
.text:00000001400019AF loc_1400019AF: ; CODE XREF: sub_140001910+72j
.text:00000001400019AF lea rdx, [rsp+448h+var_418_KeyAstr]
.text:00000001400019B4 mov ecx, eax
.text:00000001400019B6 call Hi_CheckKeyAstr_with_Mr_sub_1400014B0
; ---------------------------------------------------------------------------
(1.2.a)Hi_Init_wwA5x5_sub_140001400 中 Hi_wwKeyInfoArray5x5_140025CC0[5][5] 数据加载初始化
.text:0000000140001426 lea rbx, Hi_wwA5x5_unk_140025CC0
.text:000000014000142D mov [rsp+28h+arg_8], rbp
.text:0000000140001432 mov ebp, 5
.text:0000000140001437 mov [rsp+28h+arg_10], rdi
.text:000000014000143C nop dword ptr [rax+00h]
.text:0000000140001440
.text:0000000140001440 loc_140001440: ;-----------------------外循环5
.text:0000000140001440 mov edi, 5
.text:0000000140001445 db 66h, 66h
.text:0000000140001445 nop word ptr [rax+rax+00000000h]
.text:0000000140001450
.text:0000000140001450 loc_140001450: ; -----------------内循环5
.text:0000000140001450 mov r8, rbx
.text:0000000140001453 lea rdx, aD ; "%d"
.text:000000014000145A mov rcx, rsi
.text:000000014000145D call Hi_file_scanf_fmt_sub_140001260
.text:0000000140001462 add rbx, 4
.text:0000000140001466 sub rdi, 1
.text:000000014000146A jnz short loc_140001450
.text:000000014000146C sub rbp, 1
.text:0000000140001470 jnz short loc_140001440
.text:0000000140001472 mov rcx, rsi
.text:0000000140001475 call Hi_close_file_sub_140003AC8
(1.2.b) 注册码结构 "[M]A[Astr]"
(1.2.c) 求M的平方根的算法类似于下述python代码
可见其是通过枚举的方式求M的平方根的,
所以一旦M的平方根不是自然数,将进入"死"循环。
def getMr(M):
# for 987654321 or 874 return -1
MDecMode = pow(10,len(str(M)))
Mr = 1
while ((Mr*Mr) % MDecMode) != M:
Mr = Mr + 1
return Mr
(1.2.d)Hi_CheckKeyAstr_with_Mr_sub_1400014B0 中对 KeyMAstr 中 Astr 的使用逻辑如下
//其取值范围只能是["1","2","3","4"]组成的集合,
//其用于携带序号的乘积与注册矩阵进行异或运行,并对用于选中注册信息的二维矩阵中的元素
//从(2,2)开始,"1"、"3"分别是行、列减1,"2"、"4"使之加1
// 其中个5,7等边界常量 由 sub_140001380 函数的不同输入决定, 其对于相同的输入,输出常量固定。
/*
如
dword_140025CBC=1;dword_140025C44=0;ecx=2 经 sub_140001380 得到 dword_140025D24 = 2 //(mfun(2,2).4 + 3)
dword_140025CBC=2;dword_140025C44=0;ecx=2 经 sub_140001380 得到 dword_140025D24 = 4
dword_140025CBC=2;dword_140025C44=0;ecx=3 经 sub_140001380 得到 dword_140025D24 = 2
*/
rsi = 2
rdi = rsi = 2
r14d.row = esi = 2
r8 = rdx = AstrPtr
r12d = esi.col - 1 = 1
rbp = rsi * 5 = 10
r13d = rsi + 1 = 3
r9d = 0
while(True){
wwA5x5 ^= ((*AstrPtr)*r9d)
switch(*AstrPtr){
case "1":
r12d should < 7 //(mfun(2,2).4 + 3)
rdi < 5
r14d.row--,r13d--,r12d--,rbp--5,break;
case "2":
r13d should < 7 //(mfun(2,2).4 + 3)
rdi < 5
r14d.row++,r13d++,r12d++,rbp++5,break;
case "3":
r14d.row shoudl < 7 //(mfun(2,2).4 + 3)
esi.col < 6
esi--,rdi--,break;
case "4":
r14d.row should < 7 //(mfun(2,2).4 + 3)
esi.col < 4
esi++,rdi++,break;
default:
"注册码格式错误"
}
r9d++
AstrPtr++
if r9d >= kslen:
break
}
1.2.d.1 经过(1.2.d)上述运行得到 r14d.row=2,esi.col=2
结合 dword_140025CBC=2;dword_140025C44=0;ecx=3 经 sub_140001380 得到 dword_140025D24 = 2 常量
下述代码的比较关心为 2*Mr + Hi_wwKeyInfoArray5x5_140025CC0[r14d.row,esi.col] == Mr*3,
化简为 Hi_wwKeyInfoArray5x5_140025CC0[r14d.row.2,esi.col.2] = Mr
1.2.d.2 即对于注册码"[M]A[Astr]",对于任意满足边界条件的Astr(如1234、12341等),
可以直接构建虚假注册码9A1234、9A12341等(不一定是9,A前只要是平方数即可)输入
然后在 关键点 00000001400018A7 断下
通过dump (Hi_wwKeyInfoArray5x5_140025CC0+r14d*5*4+esi*4) 定位到M的平方根值 Mr,从而得到 M = Mr*Mr
.text:00000001400018A7 movsxd rax, esi
.text:00000001400018AA movsxd rdx, r14d
.text:00000001400018AD lea rcx, [rax+rdx*4]
.text:00000001400018B1 add rdx, rcx
.text:00000001400018B4 lea rax, Hi_wwKeyInfoArray5x5_140025CC0
.text:00000001400018BB mov ecx, cs:Hi_stepInc_2_0_2_dword_140025D24 // dword_140025D24 = 2
.text:00000001400018C1 imul ecx, edi //---------------------edi = Mr, the root of M in KeyMAstr
.text:00000001400018C4 add ecx, [rax+rdx*4]
.text:00000001400018C7 lea eax, [rdi+rdi*2]
.text:00000001400018CA cmp ecx, eax
.text:00000001400018CC lea rcx, aZUVSJ ; "恭喜你注册成功!\n"
.text:00000001400018D3 jz short loc_1400018DC
.text:00000001400018D5 lea rcx, unk_140021F90 ;
.text:00000001400018D5 ; 注册码不正确
动态调试
(2.1)上Windbg,若注册文件错误,可将CrackMe用的注册文件放在Windbg同目录下。
Executable search path is:
ModLoad: 00000001`3fd90000 00000001`3fdbb000 image00000001`3fd90000
...
ntdll!CsrSetPriorityClass+0x40:
00000000`771c1220 cc int 3
(2.2)在(1.2.d.2)中的关键点 00000001400018A7 下断bp(如下需根据实际基地址调整),然后跑起来g
0:000> bp 13fd318a7h
0:000> bl
0 e 00000001`3fd318a7 0001 (0001) 0:**** image00000001_3fd30000+0x18a7
0:000> g
(2.3)输入 9A12345 就会在相应位置断下
Breakpoint 0 hit
image00000001_3fd30000+0x18a7:
00000001`3fd318a7 4863c6 movsxd rax,esi
0:000> u rip //------------------------------------------会rip处代码反汇编
image00000001_3fd30000+0x18a7:
00000001`3fd318a7 4863c6 movsxd rax,esi
00000001`3fd318aa 4963d6 movsxd rdx,r14d
00000001`3fd318ad 488d0c90 lea rcx,[rax+rdx*4]
00000001`3fd318b1 4803d1 add rdx,rcx
00000001`3fd318b4 488d0505440200 lea rax,[image00000001_3fd30000+0x25cc0 (00000001`3fd55cc0)]
00000001`3fd318bb 8b0d63440200 mov ecx,dword ptr [image00000001_3fd30000+0x25d24 (00000001`3fd55d24)]
00000001`3fd318c1 0fafcf imul ecx,edi
00000001`3fd318c4 030c90 add ecx,dword ptr [rax+rdx*4]
0:000> r //------------------------------------------查看寄存器状态,其中 r14=row=1, rsi=col=2
rax=0000000000000002 rbx=0000000000000002 rcx=0000000000000003
rdx=0000000000000000 rsi=0000000000000002 rdi=0000000000000003
rip=000000013fd318a7 rsp=00000000001ff750 rbp=0000000000000005
r8=000000000000000c r9=0000000000000000 r10=000000013fd55cc0
r11=000000013fd55c40 r12=0000000000000000 r13=0000000000000002
r14=0000000000000001 r15=0000000000000005
iopl=0 nv up ei pl nz na pe nc
cs=0033 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000202
image00000001_3fd30000+0x18a7:
00000001`3fd318a7 4863c6 movsxd rax,esi
0:000> d (image00000001_3fd30000+0x25cc0+r14d*5*4+esi*4) //------------dump 显示目标元素(1,2)的数据,
00000001`3fd55cdc bd 00 00 00 be 01 00 00-df 01 00 00 db 01 00 00 ................
00000001`3fd55cec f6 00 00 00 04 00 00 00-f9 01 00 00 e7 01 00 00 ................
0:000> ?bd //---------------------------------------------其值为0xbd,及Mr = 0xbd
Evaluate expression: 189 = 00000000`000000bd
0:000> ?(bd*bd) //----------------------------------------------所以 M = Mr*Mr = 0xbd*0xbd >> 35721
Evaluate expression: 35721 = 00000000`00008b89
(2.4)
即输入 9A12345得到其中一个有效注册码 35721A12341
又如输入9A1234断下提取得到有效注册码 44100A1234
0:000> d (13f815cc0h+r14d*5*4+esi*4)
00000001`3f815cf0 d2 00 00 00 0c 01 00 00-12 01 00 00 17 01 00 00 ................
0:000> ?d2
Evaluate expression: 210 = 00000000`000000d2
0:000> ?(d2*d2)
Evaluate expression: 44100 = 00000000`0000ac44
只有Astr致使(2,2)的坐标不移除5*5矩阵等边界条件,就可以Dump出相应的平方根Mr确定相应的注册码。
2.第二阶段Windbg动态调试,验证部分代码性质,结合静态分析得到注册码。
1.静态分析。
(1.1)由下面中文提示信息溯源到主要业务逻辑函数体 sub_140001910,
(该信息在IDA Striing 中为乱码,直接点击跟进)
.rdata:0000000140022008 aVSI db '注册码:',0
(1.2)在下面的 sub_140001910 函数体内
a. Hi_Init_wwA5x5_sub_140001400 加载注册文件,并初始化注册信息二维数组 Hi_wwKeyInfoArray5x5_140025CC0[5][5]。
b. Hi_console_in_fmt_sub_1400012B0 格式化 "%dA%s" 请求用户输入的注册码 KeyMAstr。
c. Hi_get_Mr_for_KeyM_sub_140001300 从用户输入的 KeyMAstr 信息中的 M 获取相应的平方根 Mr。
d. Hi_CheckKeyAstr_with_Mr_sub_1400014B0 检测 KeyMAstr 的 Astr 和 Mr。
//sub_140001910 函数体主要业务逻辑
.text:0000000140001910 ; =============== S U B R O U T I N E =======================================
.text:0000000140001910
.text:0000000140001910
.text:0000000140001910 sub_140001910 proc near ; CODE XREF: sub_140001ADC+11Fp
.text:0000000140001910 ; DATA XREF: .pdata:0000000140026084o
.text:0000000140001910
.text:0000000140001910 var_428_KeyM = dword ptr -428h
.text:0000000140001910 var_418_KeyAstr = byte ptr -418h
.text:0000000140001910 var_18 = qword ptr -18h
.text:0000000140001910
.text:0000000140001910 sub rsp, 448h
.text:0000000140001917 mov rax, cs:__security_cookie
.text:000000014000191E xor rax, rsp
.text:0000000140001921 mov [rsp+448h+var_18], rax
.text:0000000140001929 xor edx, edx
.text:000000014000192B lea rcx, [rsp+448h+var_418_KeyAstr]
.text:0000000140001930 mov r8d, 400h
.text:0000000140001936 call Hi_memset_sub_140002C10 ;
.text:0000000140001936 ; memset(ecx,edx,cbszie:r8)
.text:000000014000193B lea rcx, unk_140021FA0 ;
.text:000000014000193B ; 请将序列号文件存放在程序运行目录下,并命名为names.in 格式参见帖子
.text:000000014000193B ; By 无名侠
.text:0000000140001942 call Hi_Console_out_sub_140001200
.text:0000000140001947 call Hi_Init_wwA5x5_sub_140001400
.text:000000014000194C test al, al
.text:000000014000194E jz short loc_140001995
.text:0000000140001950 lea rcx, aVSI ; "注册码:"
.text:0000000140001957 call Hi_Console_out_sub_140001200
.text:000000014000195C lea r8, [rsp+448h+var_418_KeyAstr]
.text:0000000140001961 lea rdx, [rsp+448h+var_428_KeyM]
.text:0000000140001966 lea rcx, aDaS ; "%dA%s"
.text:000000014000196D call Hi_console_in_fmt_sub_1400012B0
.text:0000000140001972 call Hi_end0_sub_14000A634
.text:0000000140001977 mov ecx, [rsp+448h+var_428_KeyM]
.text:000000014000197B call Hi_get_Mr_for_KeyM_sub_140001300
.text:0000000140001980 test eax, eax
.text:0000000140001982 jnz short loc_1400019AF
.text:0000000140001984 lea rcx, unk_140022018 ;
.text:0000000140001984 ; 注册码有误!
.text:000000014000198B call Hi_Console_out_sub_140001200
.text:0000000140001990 call Hi_end0_sub_14000A634
.text:0000000140001995
.text:0000000140001995 loc_140001995: ; CODE XREF: sub_140001910+3Ej
.text:0000000140001995 xor eax, eax
.text:0000000140001997 mov rcx, [rsp+448h+var_18]
.text:000000014000199F xor rcx, rsp
.text:00000001400019A2 call sub_1400019D0
.text:00000001400019A7 add rsp, 448h
.text:00000001400019AE retn
.text:00000001400019AF
.text:00000001400019AF
.text:00000001400019AF loc_1400019AF: ; CODE XREF: sub_140001910+72j
.text:00000001400019AF lea rdx, [rsp+448h+var_418_KeyAstr]
.text:00000001400019B4 mov ecx, eax
.text:00000001400019B6 call Hi_CheckKeyAstr_with_Mr_sub_1400014B0
; ---------------------------------------------------------------------------
(1.2.a)Hi_Init_wwA5x5_sub_140001400 中 Hi_wwKeyInfoArray5x5_140025CC0[5][5] 数据加载初始化
.text:0000000140001426 lea rbx, Hi_wwA5x5_unk_140025CC0
.text:000000014000142D mov [rsp+28h+arg_8], rbp
.text:0000000140001432 mov ebp, 5
.text:0000000140001437 mov [rsp+28h+arg_10], rdi
.text:000000014000143C nop dword ptr [rax+00h]
.text:0000000140001440
.text:0000000140001440 loc_140001440: ;-----------------------外循环5
.text:0000000140001440 mov edi, 5
.text:0000000140001445 db 66h, 66h
.text:0000000140001445 nop word ptr [rax+rax+00000000h]
.text:0000000140001450
.text:0000000140001450 loc_140001450: ; -----------------内循环5
.text:0000000140001450 mov r8, rbx
.text:0000000140001453 lea rdx, aD ; "%d"
.text:000000014000145A mov rcx, rsi
.text:000000014000145D call Hi_file_scanf_fmt_sub_140001260
.text:0000000140001462 add rbx, 4
.text:0000000140001466 sub rdi, 1
.text:000000014000146A jnz short loc_140001450
.text:000000014000146C sub rbp, 1
.text:0000000140001470 jnz short loc_140001440
.text:0000000140001472 mov rcx, rsi
.text:0000000140001475 call Hi_close_file_sub_140003AC8
(1.2.b) 注册码结构 "[M]A[Astr]"
(1.2.c) 求M的平方根的算法类似于下述python代码
可见其是通过枚举的方式求M的平方根的,
所以一旦M的平方根不是自然数,将进入"死"循环。
def getMr(M):
# for 987654321 or 874 return -1
MDecMode = pow(10,len(str(M)))
Mr = 1
while ((Mr*Mr) % MDecMode) != M:
Mr = Mr + 1
return Mr
(1.2.d)Hi_CheckKeyAstr_with_Mr_sub_1400014B0 中对 KeyMAstr 中 Astr 的使用逻辑如下
//其取值范围只能是["1","2","3","4"]组成的集合,
//其用于携带序号的乘积与注册矩阵进行异或运行,并对用于选中注册信息的二维矩阵中的元素
//从(2,2)开始,"1"、"3"分别是行、列减1,"2"、"4"使之加1
// 其中个5,7等边界常量 由 sub_140001380 函数的不同输入决定, 其对于相同的输入,输出常量固定。
/*
如
dword_140025CBC=1;dword_140025C44=0;ecx=2 经 sub_140001380 得到 dword_140025D24 = 2 //(mfun(2,2).4 + 3)
dword_140025CBC=2;dword_140025C44=0;ecx=2 经 sub_140001380 得到 dword_140025D24 = 4
dword_140025CBC=2;dword_140025C44=0;ecx=3 经 sub_140001380 得到 dword_140025D24 = 2
*/
rsi = 2
rdi = rsi = 2
r14d.row = esi = 2
r8 = rdx = AstrPtr
r12d = esi.col - 1 = 1
rbp = rsi * 5 = 10
r13d = rsi + 1 = 3
r9d = 0
while(True){
wwA5x5 ^= ((*AstrPtr)*r9d)
switch(*AstrPtr){
case "1":
r12d should < 7 //(mfun(2,2).4 + 3)
rdi < 5
r14d.row--,r13d--,r12d--,rbp--5,break;
case "2":
r13d should < 7 //(mfun(2,2).4 + 3)
rdi < 5
r14d.row++,r13d++,r12d++,rbp++5,break;
case "3":
r14d.row shoudl < 7 //(mfun(2,2).4 + 3)
esi.col < 6
esi--,rdi--,break;
case "4":
r14d.row should < 7 //(mfun(2,2).4 + 3)
esi.col < 4
esi++,rdi++,break;
default:
"注册码格式错误"
}
r9d++
AstrPtr++
if r9d >= kslen:
break
}
1.2.d.1 经过(1.2.d)上述运行得到 r14d.row=2,esi.col=2
结合 dword_140025CBC=2;dword_140025C44=0;ecx=3 经 sub_140001380 得到 dword_140025D24 = 2 常量
下述代码的比较关心为 2*Mr + Hi_wwKeyInfoArray5x5_140025CC0[r14d.row,esi.col] == Mr*3,
化简为 Hi_wwKeyInfoArray5x5_140025CC0[r14d.row.2,esi.col.2] = Mr
1.2.d.2 即对于注册码"[M]A[Astr]",对于任意满足边界条件的Astr(如1234、12341等),
可以直接构建虚假注册码9A1234、9A12341等(不一定是9,A前只要是平方数即可)输入
然后在 关键点 00000001400018A7 断下
通过dump (Hi_wwKeyInfoArray5x5_140025CC0+r14d*5*4+esi*4) 定位到M的平方根值 Mr,从而得到 M = Mr*Mr
.text:00000001400018A7 movsxd rax, esi
.text:00000001400018AA movsxd rdx, r14d
.text:00000001400018AD lea rcx, [rax+rdx*4]
.text:00000001400018B1 add rdx, rcx
.text:00000001400018B4 lea rax, Hi_wwKeyInfoArray5x5_140025CC0
.text:00000001400018BB mov ecx, cs:Hi_stepInc_2_0_2_dword_140025D24 // dword_140025D24 = 2
.text:00000001400018C1 imul ecx, edi //---------------------edi = Mr, the root of M in KeyMAstr
.text:00000001400018C4 add ecx, [rax+rdx*4]
.text:00000001400018C7 lea eax, [rdi+rdi*2]
.text:00000001400018CA cmp ecx, eax
.text:00000001400018CC lea rcx, aZUVSJ ; "恭喜你注册成功!\n"
.text:00000001400018D3 jz short loc_1400018DC
.text:00000001400018D5 lea rcx, unk_140021F90 ;
.text:00000001400018D5 ; 注册码不正确
动态调试
(2.1)上Windbg,若注册文件错误,可将CrackMe用的注册文件放在Windbg同目录下。
Executable search path is:
ModLoad: 00000001`3fd90000 00000001`3fdbb000 image00000001`3fd90000
...
ntdll!CsrSetPriorityClass+0x40:
00000000`771c1220 cc int 3
(2.2)在(1.2.d.2)中的关键点 00000001400018A7 下断bp(如下需根据实际基地址调整),然后跑起来g
0:000> bp 13fd318a7h
0:000> bl
0 e 00000001`3fd318a7 0001 (0001) 0:**** image00000001_3fd30000+0x18a7
0:000> g
(2.3)输入 9A12345 就会在相应位置断下
Breakpoint 0 hit
image00000001_3fd30000+0x18a7:
00000001`3fd318a7 4863c6 movsxd rax,esi
0:000> u rip //------------------------------------------会rip处代码反汇编
image00000001_3fd30000+0x18a7:
00000001`3fd318a7 4863c6 movsxd rax,esi
00000001`3fd318aa 4963d6 movsxd rdx,r14d
00000001`3fd318ad 488d0c90 lea rcx,[rax+rdx*4]
00000001`3fd318b1 4803d1 add rdx,rcx
00000001`3fd318b4 488d0505440200 lea rax,[image00000001_3fd30000+0x25cc0 (00000001`3fd55cc0)]
00000001`3fd318bb 8b0d63440200 mov ecx,dword ptr [image00000001_3fd30000+0x25d24 (00000001`3fd55d24)]
00000001`3fd318c1 0fafcf imul ecx,edi
00000001`3fd318c4 030c90 add ecx,dword ptr [rax+rdx*4]
0:000> r //------------------------------------------查看寄存器状态,其中 r14=row=1, rsi=col=2
rax=0000000000000002 rbx=0000000000000002 rcx=0000000000000003
rdx=0000000000000000 rsi=0000000000000002 rdi=0000000000000003
rip=000000013fd318a7 rsp=00000000001ff750 rbp=0000000000000005
r8=000000000000000c r9=0000000000000000 r10=000000013fd55cc0
r11=000000013fd55c40 r12=0000000000000000 r13=0000000000000002
r14=0000000000000001 r15=0000000000000005
iopl=0 nv up ei pl nz na pe nc
cs=0033 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000202
image00000001_3fd30000+0x18a7:
00000001`3fd318a7 4863c6 movsxd rax,esi
0:000> d (image00000001_3fd30000+0x25cc0+r14d*5*4+esi*4) //------------dump 显示目标元素(1,2)的数据,
00000001`3fd55cdc bd 00 00 00 be 01 00 00-df 01 00 00 db 01 00 00 ................
00000001`3fd55cec f6 00 00 00 04 00 00 00-f9 01 00 00 e7 01 00 00 ................
0:000> ?bd //---------------------------------------------其值为0xbd,及Mr = 0xbd
Evaluate expression: 189 = 00000000`000000bd
0:000> ?(bd*bd) //----------------------------------------------所以 M = Mr*Mr = 0xbd*0xbd >> 35721
Evaluate expression: 35721 = 00000000`00008b89
(2.4)
即输入 9A12345得到其中一个有效注册码 35721A12341
又如输入9A1234断下提取得到有效注册码 44100A1234
0:000> d (13f815cc0h+r14d*5*4+esi*4)
00000001`3f815cf0 d2 00 00 00 0c 01 00 00-12 01 00 00 17 01 00 00 ................
0:000> ?d2
Evaluate expression: 210 = 00000000`000000d2
0:000> ?(d2*d2)
Evaluate expression: 44100 = 00000000`0000ac44
只有Astr致使(2,2)的坐标不移除5*5矩阵等边界条件,就可以Dump出相应的平方根Mr确定相应的注册码。
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
赞赏
他的文章
- [原创] KCTF 2022 Win. 第六题 约束与伪随机 6745
- [原创] KCTF 2021 Win. 第二题 排排坐 21175
- [原创] KCTF 2021 Win. 第一题 算力与攻击模式 4118
- 鸿蒙通识 26032
- [原创] KCTF 2021 Spr. 第二题 未选择的路 9250
看原图
赞赏
雪币:
留言: