关于对加壳后DLL的调试分析的笔记

来源:互联网 发布:天书残卷辅助软件 编辑:程序博客网 时间:2024/05/22 20:01

这个是很久之前分析一个DLL时的文章了。写在了QQ空间里面。现在翻出来,慰问下自己。

其实不算是高明的东西。之前在分析一个样本时,该样本释放出了一个DLL,由于脱壳的功力不够强悍,但是便于分析。就自己写了个程序来调用。OnlyDBG虽然可以LoadDll插件来加载,但是个人感觉复杂(也许是没有用好的关系),我更喜欢此种方式,代码简陋,不要耻笑:)

 

有如下代码片段

#include <windows.h>
#include <stdio.h>

 

_declspec (dllexport)  void  FuncationName(ParamType Param,...);

 

int main(int argc ,char *argv[])
{
   HMODULE  hDll = NULL;
   FARPROC  FunAddr;
 
   hDll = LoadLibrary("DllName.dll");
 if(hDll==INVALID_HANDLE_VALUE)
 {
  printf("dll load fail/r/n");
  return 0;
 }
 else
 {
  FunAddr = GetProcAddress(hDll,"FuncationName");
  if(FunAddr==NULL) return 0;
  __asm CALL FunAddr
 }

  FreeLibrary(hDll);
 return 0;
}

 

我们知道DLL是不能够像exe那样运行的,是被动态加载的。所以在调试的时候很不方便,因为单单在IDA的静态反汇编工具里面,你没有办法看到寄存器的变化情况。既然DLL能被其他程序调用,那么就很好办了,自己实现一个测试程序加载之就可以了。但是这里涉及到一个问题,就是导出函数。DLL都有导出函数,但是加壳过后是否也有导出函数呢?回答是肯定的。如果你了解一些PE文件的知识,你就知道EXE这样的文件不需要重定位,但是DLL却不同,不同的机器,dll被加载到内存中的地址是不一样的,这也就是为什么DLL一般都有重定位节的原因。所以,作者不可能无聊到要通过使用直接地址的形式,我的意思是说假如有一个DLL被加载到内存中后,其中的一个Funcation地址为0x11111111(我这个只是假设),那么在他的程序中采取这样的形式:

__asm    call   0x11111111

我想,这样多半要出问题。所以,要动计算函数的地址,但是又太麻烦。而将一个函数声明为导出函数却方便了很多,事实上也正是这样做的。所以我们只需要得到这个导出函数的地址,那么便可以跟进去看个究竟了。函数的名字很容易获取到,你可以使用VC的一个Depends去查看导出的函数名字。有了名字,就可以用上面的代码获取到该函数的地址了。我这的代码堆栈肯定没有平衡,但是我想,作为一个测试例子,应该还是足够了。

 

接下来就是将我们自己的程序加载到调试器当中,然后下好断点,就可以跟踪DLL中的函数了。非常方便。不过我这个只是一般的情况,其他的没有遇到过,只是一个思路而已。欢迎拍砖

 

原创粉丝点击