re笔记1

polar 简单re-shell
打开后查壳,用upx -d 脱壳
找到主函数(其实不是主函数,没加载完导致跳转错了)
// attributes: thunk int __stdcall sub_45CC60(int a1, int a2, int a3, int a4, int a5) { return sub_4795E0(a1, a2, a3, a4, a5); }
attributes有注释和属性的意思在这里是注释,thunk是跳板的意思
接着跟进sub——4795E0函数
_DWORD *__thiscall sub_4795E0(_DWORD *this, int a2, _DWORD *a3, _DWORD *a4, _DWORD *a5, _DWORD *a6) { j_unknown_libname_213(a2, *a3, a3[1], *a4, *a5, *a6); this[276] = 0; return this; }
DWORD *表示32位无符号整型指针,无符号表示数值是大于等于0,int或者在IDA中的LONG表示有符号整型,第一位0为正数为1则是负数.
__thiscall表示一种约定,__this规定了参数压栈方式是从右到左,以及自身调用结束后清栈,call则是CPU指令,首先把下一个EIP地址(返回地址)压进栈,然后跳过去,保证在最后被调函数尾部跳回.换句话说就是__thiscall → this 走 ECX,其余 5 个参数压栈,被调方 ret 14h 清栈。
J_的意思就是jump thunk 跳转桩,节省一次ret
this[276]=0就是进入this内存把 偏移 0x450 字节 的 4 字节字段清零。注意276x4=1106(十进制)=0x450(十六进制)
接着跟进j_unknown_libname_213
// attributes: thunk int __stdcall j_unknown_libname_213(int a1, int a2, int a3, int a4, int a5, int a6) { return unknown_libname_213(a1, a2, a3, a4, a5, a6); }
又是一个跳板,而且是一个纯跳板,J_标记就是说调用流直接穿过去,不占额外栈空间,也不产生任何副作用。
继续跟进unknown_libname_213
// Microsoft VisualC universal runtime _DWORD *__thiscall unknown_libname_213(_DWORD *this, _DWORD *a2, int a3, int a4, int a5, int a6, int a7) { __crt_stdio_output::common_data<wchar_t>::common_data<wchar_t>(this); this[274] = *a2; *this = a3; this[1] = a4; this[2] = a6; this[4] = a5; this[5] = a7; return this; }
好了,到这就分析不动了,发现原来不是main函数,直接重新加载f5进去后直接看到flag
image

posted @ 2025-11-24 18:31  CLAY666  阅读(2)  评论(0)    收藏  举报