首页
社区
课程
招聘
如何获得调试版本DLL的API函数的参数类型和返回值类型[原创]
发表于: 2006-7-17 16:34 5959

如何获得调试版本DLL的API函数的参数类型和返回值类型[原创]

2006-7-17 16:34
5959
//用MS C++编译出来的调试版本的DLL的API函数是类似这样的形式:?apiname@@YA_NEEPAD@Z,
//这里面包函了参数类型和返回值类型,下面是我分析出来的类型表示
//YA:返回值
//PA:指针
//PB:常量指针
//_N bool
//D : char
//E :unsigned char
//F :short
//G :unsigned short
//H : int
//I :unsigned int;
//J :long
//K :unsigned long
//M :float
//N :double
//O :long double
//X :void
//T :union
//U :structure
//Z :参数结束标志
//这样,上面这个API实际上是:bool apiname(BYTE,BYTE,char*)
//许多的反汇编程序都有自动分析调试版本API的功能,如IDA Pro,debugapispy等
//知道了函数的声明会给我们带来很多的方便,例如你在反汇编一个调试版本的DLL的时候.
//而将这样的API还原成编译前的API也不会太难.
//我写了一个这样的小程序,确实给自己带来了很大方便,但我权限不够,不能上转啊
//或许可以将这个功能写成一个OllyDBG的插件,呵呵,如果有人写出来,别忘了发给我一份:)

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (4)
雪    币: 153
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
这个函数就可以了。
  UnDecorateSymbolName
2006-7-17 18:33
0
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
谢谢楼上的,我一直想找一个相关的函数,但是都找不到,这才自己分析了一下,不过,花这点时间也是值得的,再一次感谢.
2006-7-18 09:35
0
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
我将源程序改了一下,贴出来,希望对大家有帮助.
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include <imagehlp.h>
#pragma comment(lib,"kernel32.lib")
#pragma comment(lib,"user32.lib")
#pragma comment(lib,"dbghelp.lib")
//下面这两个函数是由彭春华的TestDebug中的API分析函数改来的
void AnalysisExportFunction(void *pAddBase, const char* szDllName)
        {
         PIMAGE_DOS_HEADER pdosHdr;
         PIMAGE_NT_HEADERS pntHdr;
         char decodestr[256];
         memset(decodestr,0,256);
         pdosHdr = (PIMAGE_DOS_HEADER)pAddBase;
        // 检查是不是PE文件
         if(pdosHdr->e_magic != IMAGE_DOS_SIGNATURE)
          return;
                // 计算偏移量,跳过DOS检查代码
         pntHdr = (PIMAGE_NT_HEADERS)(pdosHdr->e_lfanew + (DWORD)pAddBase);
         if(pntHdr->Signature != IMAGE_NT_SIGNATURE)
          return;
         PIMAGE_EXPORT_DIRECTORY pExport;
         DWORD dwSize;
        // 得到导出表的地址
         pExport = (PIMAGE_EXPORT_DIRECTORY)ImageDirectoryEntryToData(pAddBase, false,
          IMAGE_DIRECTORY_ENTRY_EXPORT, &dwSize);
        // 有没有导出表
         if(pExport == NULL)
          return ;
         DWORD pExportBegin, pExportEnd;
        // 得到导出表的在内存中的地址和大小
         pExportBegin = (DWORD)pntHdr->OptionalHeader.DataDirectory[
          IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
         pExportEnd = pExportBegin + dwSize;
         PWORD pOrdFun;
        // 得到函数名指针
         char**  spName = (char**)ImageRvaToVa(pntHdr, pAddBase, pExport->AddressOfNames, 0);
        // 得到函数的入口地址指针
         PDWORD pFun = (PDWORD)ImageRvaToVa(pntHdr, pAddBase,
          pExport->AddressOfFunctions, 0);
        // 得到函数顺序表指针
         pOrdFun  = (PWORD)ImageRvaToVa(pntHdr, pAddBase, pExport->AddressOfNameOrdinals, 0);
         if(pFun == 0)
          return;
         // 得到函数名及函数入口地址
         for(int i = 0; i<pExport->NumberOfFunctions; i++)
         {
          char* pName = 0;
        // 得到函数入口指针
          DWORD pFunPoint = *(pFun + i);
          if(pFunPoint == 0)
           continue;
        // DLL的Forword函数不处理
          if(pFunPoint > pExportBegin && pFunPoint < pExportEnd)
           continue;
        // 根据顺序号得到函数名
          for(int j = 0; j<pExport->NumberOfNames; j++)
          {
           if(*(pOrdFun + j) == i)
           {
                pName = (char*)ImageRvaToVa(pntHdr, pAddBase, (ULONG)*(spName + j), 0);
                break;
           }
          }
          if(pName)
          {
                  UnDecorateSymbolName(pName,decodestr,256,UNDNAME_COMPLETE);
                  printf("%s\n",decodestr);          
          }
         }
}

void AnalysisFunction(const char* szDllName)
{
HANDLE hFile = CreateFile(szDllName,
GENERIC_READ,
FILE_SHARE_READ |FILE_SHARE_WRITE,
  0,
OPEN_EXISTING,
FILE_FLAG_SEQUENTIAL_SCAN,
0);
if (hFile ==INVALID_HANDLE_VALUE)
        {
                printf("could not open file");
        }
HANDLE hMap = CreateFileMapping(hFile, 0, PAGE_READONLY, 0, 0, 0);
if(hMap == 0) // 失败
{
  CloseHandle(hFile);
  printf("Create Map file failed\n");
  return;
}
LPVOID pMap = MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0);
if(pMap)
{
  AnalysisExportFunction(pMap, szDllName);
}
    UnmapViewOfFile(pMap);
    CloseHandle(hMap);
    CloseHandle(hFile);
}
void main(int argc, const TCHAR* argv[] )
{
        if(argc<2)
                {
                        printf("usage: decode.exe dllname\n");
                        return;
                }
        AnalysisFunction(argv[1]);
}
2006-7-18 09:50
0
雪    币: 257
活跃值: (369)
能力值: ( LV12,RANK:370 )
在线值:
发帖
回帖
粉丝
5
开源支持!
2006-7-18 11:15
0
游客
登录 | 注册 方可回帖
返回
//