-
-
[原创]看雪 2016 CTF 第二十四 Solution
-
发表于: 2016-12-20 21:23 2490
-
在消息响应函数Hi_ctrl_WM_COMMAND_handler_sub_403E80中
通过调用Hi_update_sub_41C31A(True)更新编辑框内容到关联的控件成员变量中
.text:00403EB2 push 1
.text:00403EB4 mov ecx, [ebp+var_118_thisPtr]
.text:00403EBA call Hi_update_sub_41C31A
通过调用Hi_update_sub_41C31A中调用Hi_getEditText_sub_403B60
0041C361 call dword ptr [eax+100h] ; Hi_getEditText_sub_403B60
Hi_getEditText_sub_403B60如下,可见edit控件关联的字符串成员变量在偏移thisPtr.C0h处
.text:00403B63 lea eax, [ecx+0C0h]
.text:00403B69 push eax ; int
.text:00403B6A push 3E9h ; nIDDlgItem
.text:00403B6F push [ebp+arg_0] ; int
.text:00403B72 call Hi_InP2DlgID_OutP3text_sub_416F7A
下述代码将注册码通过Hi_P2CStr_spliteAt5_to_ecx2CStrA1A2_retA2_sub_402D30函数分成
两部分粗放于两个元素的CStr数组中var_18_2Cstr。分割边界是前五个字符为key1,剩下的为key2
即 key = key1 + key2
.text:00403EEE mov eax, [ebp+var_118_thisPtr]
.text:00403EF4 add eax
....
.text:00403F17 push esi ; void *
.text:00403F18 lea ecx, [ebp+var_18_2Cstr]
.text:00403F1B call Hi_P2CStr_spliteAt5_to_ecx2CStrA1A2_retA2_sub_402D30
在重入函数Hi_checkKey1_or_expandKey_sub_403230中,第一此调用该函数体时会触发对key1的校验分支。
.text:00403F65 lea ecx, [ebp+var_18_2Cstr]
.text:00403F68 call Hi_getCStrPtr_sub_404280
.text:00403F6D push eax ; Src
.text:00403F6E lea ecx, [ebp+var_30_key1]
.text:00403F71 call Hi_checkKey1_or_expandKey_sub_403230
Hi_checkFlag_dword_5982E4 = 1
Hi_checkKey1_or_expandKey_sub_403230校验
if Hi_checkFlag_dword_5982E4 == 1:
Hi_check_key1_sub_403510 //校验key1
else:
Hi_DecExpand_sub_403650 //保留的key信息变换函数,本样例不使用
在Hi_check_key1_sub_403510中
调用0040354E call Hi_extract_key1_sub_4032C0解密释放出对比的rkey1,随后将rkey1与key1明文对比,
即只需要在40356D断下,观测ecx和eax寄存器指向的缓冲区即可得到key1\rkey1=pediy
比对正确后,会对Hi_checkFlag_dword_5982E4清零,后续重入Hi_checkKey1_or_expandKey_sub_403230函数
时就不会重复校验。而另一分支只是将相应的key信息(如key1)变换为其它形式。
下述Hi_2HexTo1Bin_Xor0x86_sub_402E20函数将key2字符串识别为十六进制数据,
即key2的每两个十六进制字符转换对应的字节数值,并用0x86异或加密处理
00404069 call Hi_2HexTo1Bin_Xor0x86_sub_402E20
紧接着就是将key2转换加密的数据与正确的加密信息var_10C_rKey2对比
.text:00404077 mov ecx, [ebp+var_108_rKey2Len]
.text:0040407D push ecx
.text:0040407E mov edx, [ebp+var_10C_rKey2]
.text:00404084 push edx
.text:00404085 mov eax, [ebp+var_1C_cxkey2Len]
.text:00404088 push eax
.text:00404089 mov ecx, [ebp+var_11C_cxkey2]
.text:0040408F push ecx
.text:00404090 lea ecx, [ebp+var_58_keytext]
.text:00404093 call Hi_Check_cxKey2_sub_403910
即在00404093处断下,查看var_10C_rKey2缓冲区,0x9C大小的内容即为
key2转换异或加密后的内容,这里是half字节分开
001AE608 01 04 08 02 04 08 03 04 08 04 04 08 05 04 08 06
001AE618 04 08 07 04 08 08 04 08 09 04 08 01 04 08 02 04
001AE628 08 03 04 08 04 04 08 05 04 08 06 04 08 07 04 08
001AE638 08 04 08 09 04 08 01 04 08 02 04 08 03 04 08 04
001AE648 04 08 05 04 08 06 04 08 07 04 08 08 04 08 09 04
001AE658 08 01 04 08 02 04 08 03 04 08 04 04 08 05 04 08
001AE668 06 04 08 07 04 08 08 04 08 09 04 08 01 04 08 02
001AE678 04 08 03 04 08 04 04 08 05 04 08 06 04 08 07 04
001AE688 08 08 04 08 09 04 08 01 04 08 02 04 08 03 04 08
001AE698 04 04 08 05 04 08 06 04 08 00 00 00
将IDA(WINDBG)命令切换到IDAPython模式,执行#-------之间的代码即可之间提取加密得到key2
#-------
b = []
for i in xrange(0,0x9C):
bbea = 0x1AE608+i
cxb = ((Byte(bbea)+0x30)&0xFF)^0x86
b.append("{:02X}".format(cxb))
key2 = b"".join(b)
#-------
key2=
B7B2BEB4B2BEB5B2BEB2B2BE \
B3B2BEB0B2BEB1B2BEBEB2BE \
BFB2BEB7B2BEB4B2BEB5B2BE \
B2B2BEB3B2BEB0B2BEB1B2BE \
BEB2BEBFB2BEB7B2BEB4B2BE \
B5B2BEB2B2BEB3B2BEB0B2BE \
B1B2BEBEB2BEBFB2BEB7B2BE \
B4B2BEB5B2BEB2B2BEB3B2BE \
B0B2BEB1B2BEBEB2BEBFB2BE \
B7B2BEB4B2BEB5B2BEB2B2BE \
B3B2BEB0B2BEB1B2BEBEB2BE \
BFB2BEB7B2BEB4B2BEB5B2BE \
B2B2BEB3B2BEB0B2BEB6B6B6 \
于是得到注册码key=key1+key2=pediyB7B2BEB4B2BEB5B2BEB2B2BEB3B2BEB0B2BEB1B2BEBEB2BEBFB2BEB7B2BEB4B2BEB5B2BEB2B2BEB3B2BEB0B2BEB1B2BEBEB2BEBFB2BEB7B2BEB4B2BEB5B2BEB2B2BEB3B2BEB0B2BEB1B2BEBEB2BEBFB2BEB7B2BEB4B2BEB5B2BEB2B2BEB3B2BEB0B2BEB1B2BEBEB2BEBFB2BEB7B2BEB4B2BEB5B2BEB2B2BEB3B2BEB0B2BEB1B2BEBEB2BEBFB2BEB7B2BEB4B2BEB5B2BEB2B2BEB3B2BEB0B2BEB6B6B6
这种静态编译的程序会由于ATL String ,basic_string<>关联函数的识别上增加逆向难度
以下是部分手工重命名的函数。
Hi_2HexTo1Bin_Xor0x86_sub_402E20
Hi_AFX_MODULE_THREAD_STATE_ctor_sub_4066D2
Hi_AFX_THREAD_STATE_ctor_sub_405F63
Hi_AfxGetStringManager
Hi_CStr_Mid_sPos_chSize_sub_404160
Hi_CStr_dotr_sub_402C70
Hi_CStr_getLen_sub_4029D0
Hi_DecExpand_sub_403650
Hi_IDDlg_2_hWnd_sub_417026
Hi_InP2DlgID_OutP3text_sub_416F7A
Hi_P1_EQ_EcxLeftNStr_sub_404210
Hi_P2CStr_spliteAt5_to_ecx2CStrA1A2_retA2_sub_402D30
Hi_RaiseException_sub_405F15
Hi_afxstr_ecx_eq_p1_sub_404830
Hi_bastr_ecx_eq_P1lpsz_P2len_sub_401EE0
Hi_bastr_trim_sub_412460
Hi_bstrReserve_sub_416A1D
Hi_checkKey1_or_expandKey_sub_403230
Hi_check_key1_sub_403510
Hi_chset_index_sub_4043C0
Hi_ecxCStr_eq_P1CStr_sub_4048C0
Hi_extract_key1_sub_4032C0
Hi_free_sub_4AEF5F
Hi_getCStrPtr_sub_404280
Hi_getEditText_sub_403B60
Hi_getNilString_sub_4050C2
Hi_getThis_sub_402080
Hi_get_AFX_THREAD_STATE_sub_416D28
Hi_keyMsgMap_sub_4151F8
Hi_malloc_sub_404B6B
Hi_malloc_sub_404F1F
Hi_memset_ecx_0_cbSizeP1_sub_402620
Hi_realloc_sub_405198
通过调用Hi_update_sub_41C31A(True)更新编辑框内容到关联的控件成员变量中
.text:00403EB2 push 1
.text:00403EB4 mov ecx, [ebp+var_118_thisPtr]
.text:00403EBA call Hi_update_sub_41C31A
通过调用Hi_update_sub_41C31A中调用Hi_getEditText_sub_403B60
0041C361 call dword ptr [eax+100h] ; Hi_getEditText_sub_403B60
Hi_getEditText_sub_403B60如下,可见edit控件关联的字符串成员变量在偏移thisPtr.C0h处
.text:00403B63 lea eax, [ecx+0C0h]
.text:00403B69 push eax ; int
.text:00403B6A push 3E9h ; nIDDlgItem
.text:00403B6F push [ebp+arg_0] ; int
.text:00403B72 call Hi_InP2DlgID_OutP3text_sub_416F7A
下述代码将注册码通过Hi_P2CStr_spliteAt5_to_ecx2CStrA1A2_retA2_sub_402D30函数分成
两部分粗放于两个元素的CStr数组中var_18_2Cstr。分割边界是前五个字符为key1,剩下的为key2
即 key = key1 + key2
.text:00403EEE mov eax, [ebp+var_118_thisPtr]
.text:00403EF4 add eax
....
.text:00403F17 push esi ; void *
.text:00403F18 lea ecx, [ebp+var_18_2Cstr]
.text:00403F1B call Hi_P2CStr_spliteAt5_to_ecx2CStrA1A2_retA2_sub_402D30
在重入函数Hi_checkKey1_or_expandKey_sub_403230中,第一此调用该函数体时会触发对key1的校验分支。
.text:00403F65 lea ecx, [ebp+var_18_2Cstr]
.text:00403F68 call Hi_getCStrPtr_sub_404280
.text:00403F6D push eax ; Src
.text:00403F6E lea ecx, [ebp+var_30_key1]
.text:00403F71 call Hi_checkKey1_or_expandKey_sub_403230
Hi_checkFlag_dword_5982E4 = 1
Hi_checkKey1_or_expandKey_sub_403230校验
if Hi_checkFlag_dword_5982E4 == 1:
Hi_check_key1_sub_403510 //校验key1
else:
Hi_DecExpand_sub_403650 //保留的key信息变换函数,本样例不使用
在Hi_check_key1_sub_403510中
调用0040354E call Hi_extract_key1_sub_4032C0解密释放出对比的rkey1,随后将rkey1与key1明文对比,
即只需要在40356D断下,观测ecx和eax寄存器指向的缓冲区即可得到key1\rkey1=pediy
比对正确后,会对Hi_checkFlag_dword_5982E4清零,后续重入Hi_checkKey1_or_expandKey_sub_403230函数
时就不会重复校验。而另一分支只是将相应的key信息(如key1)变换为其它形式。
下述Hi_2HexTo1Bin_Xor0x86_sub_402E20函数将key2字符串识别为十六进制数据,
即key2的每两个十六进制字符转换对应的字节数值,并用0x86异或加密处理
00404069 call Hi_2HexTo1Bin_Xor0x86_sub_402E20
紧接着就是将key2转换加密的数据与正确的加密信息var_10C_rKey2对比
.text:00404077 mov ecx, [ebp+var_108_rKey2Len]
.text:0040407D push ecx
.text:0040407E mov edx, [ebp+var_10C_rKey2]
.text:00404084 push edx
.text:00404085 mov eax, [ebp+var_1C_cxkey2Len]
.text:00404088 push eax
.text:00404089 mov ecx, [ebp+var_11C_cxkey2]
.text:0040408F push ecx
.text:00404090 lea ecx, [ebp+var_58_keytext]
.text:00404093 call Hi_Check_cxKey2_sub_403910
即在00404093处断下,查看var_10C_rKey2缓冲区,0x9C大小的内容即为
key2转换异或加密后的内容,这里是half字节分开
001AE608 01 04 08 02 04 08 03 04 08 04 04 08 05 04 08 06
001AE618 04 08 07 04 08 08 04 08 09 04 08 01 04 08 02 04
001AE628 08 03 04 08 04 04 08 05 04 08 06 04 08 07 04 08
001AE638 08 04 08 09 04 08 01 04 08 02 04 08 03 04 08 04
001AE648 04 08 05 04 08 06 04 08 07 04 08 08 04 08 09 04
001AE658 08 01 04 08 02 04 08 03 04 08 04 04 08 05 04 08
001AE668 06 04 08 07 04 08 08 04 08 09 04 08 01 04 08 02
001AE678 04 08 03 04 08 04 04 08 05 04 08 06 04 08 07 04
001AE688 08 08 04 08 09 04 08 01 04 08 02 04 08 03 04 08
001AE698 04 04 08 05 04 08 06 04 08 00 00 00
将IDA(WINDBG)命令切换到IDAPython模式,执行#-------之间的代码即可之间提取加密得到key2
#-------
b = []
for i in xrange(0,0x9C):
bbea = 0x1AE608+i
cxb = ((Byte(bbea)+0x30)&0xFF)^0x86
b.append("{:02X}".format(cxb))
key2 = b"".join(b)
#-------
key2=
B7B2BEB4B2BEB5B2BEB2B2BE \
B3B2BEB0B2BEB1B2BEBEB2BE \
BFB2BEB7B2BEB4B2BEB5B2BE \
B2B2BEB3B2BEB0B2BEB1B2BE \
BEB2BEBFB2BEB7B2BEB4B2BE \
B5B2BEB2B2BEB3B2BEB0B2BE \
B1B2BEBEB2BEBFB2BEB7B2BE \
B4B2BEB5B2BEB2B2BEB3B2BE \
B0B2BEB1B2BEBEB2BEBFB2BE \
B7B2BEB4B2BEB5B2BEB2B2BE \
B3B2BEB0B2BEB1B2BEBEB2BE \
BFB2BEB7B2BEB4B2BEB5B2BE \
B2B2BEB3B2BEB0B2BEB6B6B6 \
于是得到注册码key=key1+key2=pediyB7B2BEB4B2BEB5B2BEB2B2BEB3B2BEB0B2BEB1B2BEBEB2BEBFB2BEB7B2BEB4B2BEB5B2BEB2B2BEB3B2BEB0B2BEB1B2BEBEB2BEBFB2BEB7B2BEB4B2BEB5B2BEB2B2BEB3B2BEB0B2BEB1B2BEBEB2BEBFB2BEB7B2BEB4B2BEB5B2BEB2B2BEB3B2BEB0B2BEB1B2BEBEB2BEBFB2BEB7B2BEB4B2BEB5B2BEB2B2BEB3B2BEB0B2BEB1B2BEBEB2BEBFB2BEB7B2BEB4B2BEB5B2BEB2B2BEB3B2BEB0B2BEB6B6B6
这种静态编译的程序会由于ATL String ,basic_string<>关联函数的识别上增加逆向难度
以下是部分手工重命名的函数。
Hi_2HexTo1Bin_Xor0x86_sub_402E20
Hi_AFX_MODULE_THREAD_STATE_ctor_sub_4066D2
Hi_AFX_THREAD_STATE_ctor_sub_405F63
Hi_AfxGetStringManager
Hi_CStr_Mid_sPos_chSize_sub_404160
Hi_CStr_dotr_sub_402C70
Hi_CStr_getLen_sub_4029D0
Hi_DecExpand_sub_403650
Hi_IDDlg_2_hWnd_sub_417026
Hi_InP2DlgID_OutP3text_sub_416F7A
Hi_P1_EQ_EcxLeftNStr_sub_404210
Hi_P2CStr_spliteAt5_to_ecx2CStrA1A2_retA2_sub_402D30
Hi_RaiseException_sub_405F15
Hi_afxstr_ecx_eq_p1_sub_404830
Hi_bastr_ecx_eq_P1lpsz_P2len_sub_401EE0
Hi_bastr_trim_sub_412460
Hi_bstrReserve_sub_416A1D
Hi_checkKey1_or_expandKey_sub_403230
Hi_check_key1_sub_403510
Hi_chset_index_sub_4043C0
Hi_ecxCStr_eq_P1CStr_sub_4048C0
Hi_extract_key1_sub_4032C0
Hi_free_sub_4AEF5F
Hi_getCStrPtr_sub_404280
Hi_getEditText_sub_403B60
Hi_getNilString_sub_4050C2
Hi_getThis_sub_402080
Hi_get_AFX_THREAD_STATE_sub_416D28
Hi_keyMsgMap_sub_4151F8
Hi_malloc_sub_404B6B
Hi_malloc_sub_404F1F
Hi_memset_ecx_0_cbSizeP1_sub_402620
Hi_realloc_sub_405198
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
赞赏
他的文章
- [原创] KCTF 2022 Win. 第六题 约束与伪随机 6745
- [原创] KCTF 2021 Win. 第二题 排排坐 21175
- [原创] KCTF 2021 Win. 第一题 算力与攻击模式 4118
- 鸿蒙通识 26032
- [原创] KCTF 2021 Spr. 第二题 未选择的路 9250
看原图
赞赏
雪币:
留言: