-
-
[原创]cybricsctf-paired
-
发表于: 2021-7-30 21:09 10300
-
解包,先得到4个文件,运行app1.exe
这几个函数不用再logic.dll里面分析,动调就可以知道是设置一个有id的储存
根据窗口类lpfnWndProc的成员根据这里找到窗口过程
这里获取edit控件字符串并检测,进入第二关
case WM_KEYDOWN(0x100):
按键要等于'ENABLE'
进入第三关
需要把消息WM_USER放入队列
这里可以加入WM_USER消息,动调查看v7函数之后,得到输入为this_is_just_some_random_string!,是fake flag,很明显不可能只分析一个文件
直接进入sub_7FF64E911210()函数分析
这里获取id==7的储存赋值给hwnd,再看前面通过第二关时
只有通过第二关,这里条件才为真, 接下来关注消息的发送, 这里所用的消息发送都将发送wparam==32的消息,执行id==64的代码,
先动调app1,进入第二关后,把断点下在第三关,然后动调app2, 运行过发送消息
v7函数, 把基地址存为id==3的储存中, 储存完成后 app2的循环停止
这里是长度检验, id==2是app1的输入框内容, 先判断不成立的情况, 这里的代码由随机数组成, srand(time(0)), 明显有很大问题
判断成立的情况
一段异或加密, 到这里
又是一段异或加密
这里有循环条件,这是其实是rbyc, id==5的由来(app1中):
输入放入id==5, 检查前面4个字节为'rbyc', 第二次异或加密
然后来到swith结构, 像极了虚拟机
然后慢慢单步走, 慢慢会发现先一直都是1, 2, 然后走5, 6, 8, 3, 8, a, 接下来就又是1, 2......., 最后, 2, 3, 4
(地址只是一个临时的值,主要怎么计算得到)
app1中的执行的代码
app1中的执行的代码
id == 7的数据换为(id==6的数据 + byte_7FF64E928A00[index + 1])
接下来会执行case 8, 将结果(1)加在 *(id==6的数据 + 8)中
这里就和app1中的加到32有点像了
这里是最后的指令, 先前的两步2, 3, 分别是把数据给到id == 7(就是每次比较的结果相加的数据)和 将id == 7与32做比较(和app1重合了), 若为真, 则id == 7 变为1
则app1中的执行的代码
这样就正确了
将id==7的数据换为(dword )(byte_7FF64E928A00 + index + 1)
app1中的执行的代码
app1中的执行的代码:
(id == 7的数据) = *(id==6的数据 + byte_7FF64E928A00[index + 1])
app2:
将 id==7 赋值给*(id == 6 + 10)
这里的1, 2指令中的其他一堆赋值貌似没什么用,主要就是每次取字符串的4个字节来加法,加数为指令3的参数(后面一个值), 结果存放在偏移量为0x10的地址中, 然后比较一下是否为32
减法解密直接python敲出来就行了
wndclass.lpfnWndProc
=
(WNDPROC)WndProc;
wndclass.lpfnWndProc
=
(WNDPROC)WndProc;
GetWindowTextA(edit_hWnd, String,
128
);
v15
=
(unsigned __int8
*
)&v19;
do
{
v16
=
v15[String
-
(CHAR
*
)&v19];
v17
=
*
v15
-
v16;
if
( v17 )
break
;
+
+
v15;
}
while
( v16 );
if
( !v17 )
{
SetWindowTextW(hWnd[
0
], L
"STAGE 2"
);
pass_to_stage2
=
1
;
}
return
0i64
;
GetWindowTextA(edit_hWnd, String,
128
);
v15
=
(unsigned __int8
*
)&v19;
do
{
v16
=
v15[String
-
(CHAR
*
)&v19];
v17
=
*
v15
-
v16;
if
( v17 )
break
;
+
+
v15;
}
while
( v16 );
if
( !v17 )
{
SetWindowTextW(hWnd[
0
], L
"STAGE 2"
);
pass_to_stage2
=
1
;
}
return
0i64
;
else
if
( pass_to_stage2
=
=
1
)
{
j
=
i;
if
( wParam !
=
aEnable[i] )
{
i
=
0
;
return
0i64
;
}
+
+
i;
if
( !aEnable[j
+
1
] )
{
pass_to_stage3
=
1
;
SetWindowTextW(_hwnd, L
"STAGE 3..."
);
add_to_storage(
1i64
, hWnd);
return
0i64
;
}
}
else
if
( pass_to_stage2
=
=
1
)
{
j
=
i;
if
( wParam !
=
aEnable[i] )
{
i
=
0
;
return
0i64
;
}
+
+
i;
if
( !aEnable[j
+
1
] )
{
pass_to_stage3
=
1
;
SetWindowTextW(_hwnd, L
"STAGE 3..."
);
add_to_storage(
1i64
, hWnd);
return
0i64
;
}
}
case
0x400u
:
/
/
WM_USER
if
( !get_flag )
{
GetWindowTextA(edit_hWnd, String,
128
);
add_to_storage(
2i64
, String);
get_flag
=
1
;
}
v7
=
VirtualAlloc(
0i64
,
0x200ui64
,
0x1000u
,
0x40u
);
get_data_from_storage((unsigned
int
)(_wParam
+
32
), v7,
128i64
);
v19
=
0i64
;
v20
=
0i64
;
v21
=
0i64
;
v22
=
0i64
;
v23
=
0i64
;
v24
=
0i64
;
v25
=
0i64
;
v26
=
0i64
;
get_data_from_storage(
2i64
, &v19,
128i64
);
success
+
=
((__int64 (__fastcall
*
)(_QWORD, __int128
*
))v7)((unsigned
int
)_wParam, &v19);
if
( success
=
=
32
)
{
MessageBoxA(
0i64
,
"Well done!"
,
"WINNER!"
,
0
);
return
0i64
;
}
case
0x400u
:
/
/
WM_USER
if
( !get_flag )
{
GetWindowTextA(edit_hWnd, String,
128
);
add_to_storage(
2i64
, String);
get_flag
=
1
;
}
v7
=
VirtualAlloc(
0i64
,
0x200ui64
,
0x1000u
,
0x40u
);
get_data_from_storage((unsigned
int
)(_wParam
+
32
), v7,
128i64
);
v19
=
0i64
;
v20
=
0i64
;
v21
=
0i64
;
v22
=
0i64
;
v23
=
0i64
;
v24
=
0i64
;
v25
=
0i64
;
v26
=
0i64
;
get_data_from_storage(
2i64
, &v19,
128i64
);
success
+
=
((__int64 (__fastcall
*
)(_QWORD, __int128
*
))v7)((unsigned
int
)_wParam, &v19);
if
( success
=
=
32
)
{
MessageBoxA(
0i64
,
"Well done!"
,
"WINNER!"
,
0
);
return
0i64
;
}
if
( pass_to_stage3 )
{
if
( wParam
=
=
'F'
)
/
/
fake
{
v11
=
0i64
;
v12
=
32i64
;
while
(
1
)
{
PostMessageA(_hwnd,
0x400u
, v11
+
+
,
0i64
);
if
( !
-
-
v12 )
break
;
_hwnd
=
hWnd[
0
];
}
}
}
if
( pass_to_stage3 )
{
if
( wParam
=
=
'F'
)
/
/
fake
{
v11
=
0i64
;
v12
=
32i64
;
while
(
1
)
{
PostMessageA(_hwnd,
0x400u
, v11
+
+
,
0i64
);
if
( !
-
-
v12 )
break
;
_hwnd
=
hWnd[
0
];
}
}
}
hWnd
=
HWND_MESSAGE|
0x2
;
LODWORD(l)
=
get_data_from_storage(
1i64
, &hWnd);
v1
=
hWnd;
if
( hWnd !
=
HWND_MESSAGE|
0x2
)
hWnd
=
HWND_MESSAGE|
0x2
;
LODWORD(l)
=
get_data_from_storage(
1i64
, &hWnd);
v1
=
hWnd;
if
( hWnd !
=
HWND_MESSAGE|
0x2
)
add_to_storage(
1i64
, hWnd);
add_to_storage(
1i64
, hWnd);
PostMessageA(v1,
0x400u
,
0x20ui64
,
0i64
);
for
( i
=
-
1i64
; i
=
=
-
1
; get_data_from_storage(
3i64
, &i) );
PostMessageA(v1,
0x400u
,
0x20ui64
,
0i64
);
for
( i
=
-
1i64
; i
=
=
-
1
; get_data_from_storage(
3i64
, &i) );
((void (__fastcall
*
)(__int64, void
*
*
, __int64))logic_dll_add_to_storage)(
3i64
, &retaddr,
8i64
);
((void (__fastcall
*
)(__int64, void
*
*
, __int64))logic_dll_add_to_storage)(
3i64
, &retaddr,
8i64
);
get_data_from_storage(
2i64
, v61);
v3
=
-
1i64
;
do
+
+
v3;
while
( v61[v3] );
if
( (_DWORD)v3
=
=
32
)
get_data_from_storage(
2i64
, v61);
v3
=
-
1i64
;
do
+
+
v3;
while
( v61[v3] );
赞赏
- [原创]SCTF low_re出题思路 14359
- [原创]l3hctf两道re的wp 8995
- [原创]强网拟态线上mobile的两道wp 22251
- [原创]android JNI静态注册和动态注册 9489
- [原创]inctf-noodes 9785