因为工作需要又再次看到了覆写的意义.
似乎大量的npm之类的东西都在使用覆写控制台而不是printf一样直接到下一行.
从探索UPX入手
所以研究一下它是如何做到覆写的.
探索记录-查找这个秘密的过程
能否在windows上覆写,我一直用疑问,因为 控制台程序 可以在自己独立的 范围内覆写,
但是在cmd运行起来的窗口呢?
如上图的效果,我们用CMD来运行我们的程序,它做到同一行读写.
现在找到答案依然是可以同样的API来覆写,互不影响。
我的探寻过程:
- 找特征
- 结果:
找到了打印的类. - 难题:
但是方法种类繁多,并不清楚是谁在干活.
而且找到的都是静态的内容.我们目的是动态的内容. - 发现:
这是回调部分才有变化.
- 结果:
- 找回调
- 结果:
找到了回调. - 难题:
有很多选择编译代码,并不清楚哪些起的作用.
也没有其他更多信息. - 发现:
upx已经编译的程序中应该有流程
- 结果:
- 分析upx-ida分析
- 结果:
被压缩了.没有结果.
- 结果:
- 解压upx-ida分析
- 结果:
字符串等能获得了,流程也能获得了. - 难题:
字符串太少.不足以轻松分析到动态部分.
打印相关导入函数被调用位置很多,难以确认是谁.
回调部分的位置也难以在满目汇编中找到. - 发现:
也许动态调试可以解决.
- 结果:
- 解压后的upx-x64dbg动态分析
加参数,使upx处于打印状态.- 结果:
在打印相关导入下了一批断点.
始终断在OutputDebugA上.
分析其参数:发现是完整的数据,并且在参数中有位置信息.
和屏幕上显示一致. - IDA分析:
确定伪代码. - 进一步:
UPX源码中找到其位置.
发现它就是putStringAttr的实现.
看其文件:平台相关.推测有更多平台方案. - 最终得到结果.
- 结果:
结果
以下是UPX打印三种平台上的代码.
他们的名字都叫putStringAttr();
djgpp2
//djggp2 DOS screen driver
ScreenPutString(位置,数据)
vcsa
//Linux /dev/vcsa screen driver
lseek(位置)
write(数据)
win32
WriteConsoleOutputA(位置,数据)