探寻逝去的Atlantis文明

打开文件发现啥都没有

运行杀毒软件提示有代码混淆器

OD挂上各种报错,估计有反调

于是从头分析,首先是两个TlsCallback

TlsCallback_0中第一个函数sub_402B30动态获取了ZwSetInformationThread设置当前线程的信息

v0 = GetModuleHandleA(&ModuleName);           // Ntdll
  v1 = GetProcAddress(v0, &ProcName);           // ZwSetInformationThread
  v2 = GetCurrentThread();
  return ((int (__stdcall *)(HANDLE, signed int, _DWORD, _DWORD))v1)(v2, 17, 0, 0);//  ThreadHideFromDebugger

百度一下可以轻松发现这个函数经常被用来反调试,第17个参数正好就是反调用的:

将其首字节改成0xc3,爆破掉即可

后一个函数sub_4028F0同样也是动态获取了4个函数的地址,将它们保存在了一个函数表中留待日后取用。其中一个是IsDebuggerPresent这样的反调函数,另外三个则是VirtualAlloc、VirtualFree和Exit这种有用的函数,因此不可简单Patch

再往后立即就调用了刚才的IsDebuggerPresent,判断到直接Exit

这里Patch或者下断过都行,小问题

TlsCallback_1里则是一个MessageBox,无关紧要

接着进入main主函数

探寻逝去的Atlantis文明

那三个连续的函数不用在意,解密代码很复杂,无需关心

sub_43180里是对Debug断点的Hook

我们知道调试器下断的原理是将某个地址的机器码改为0xcc,使其触发异常,从而被调试器捕捉中断

这个Hook会将0xcc改为0xc3,直接ret,导致不仅调试器捕捉不到断点,而且会直接令程序崩溃

这个函数里除了Hook没有别的东西,直接Patch掉

sub_403010里才是重头戏,通过memcpy将解密后的代码送入开辟出的空间中,然后直接调用

几个函数通过F8步过函数可以大致猜测出功能

关键在change_input和check两个函数中

其实当把那几个反调试通过以后就问题就不大了

动态调试跟进去,发现change_input中将Inputbase64后通过GlobalAddAtom将其加入了全局原子

再往后跟的几个函数都格外的复杂,再加上代码是动态解密的,每次都需要自己MakeCode再F5才能浏览一遍猜测是否需要详细跟踪

事实上在AddAtom之后虽然还有几个函数调用了Input的指针,但它们都是释放空间用的。

这个AddAtom添加了一个全局可用的字符串,必然在某处调用了GlobalGetAtomName

因此不妨稍微忽视一下其他函数,再往后跟

果不其然在v19,即check中捕捉到了GlobalGetAtomName的调用

该函数中生成了一个table,然后将table进行一顿操作后与Input逐字节异或,最后与另一个值进行比较—非常简单粗暴常见的逆向套路了

可以通过dump将table得到,然后效仿操作与结果数组异或从而得到flag

但更简单的方法当然是注意到这两点:

异或的逆运算还是异或

将table进行一顿操作与input完全无关

因此将结果数组直接放入Input的地址中,等到比较的时候,该地址中就是我们需要input的值了

解base64轻松得到flag。

本文章首发在 网安wangan.com 网站上。

上一篇 下一篇
讨论数量: 0
只看当前版本


暂无话题~