首页 新闻 论坛 群组 Blog 文档 下载 读书 Tag 网摘 搜索 .NET Java 游戏 视频 人才 外包 培训 数据库 书店 程序员
中国软件网
欢迎您:游客 | 登录 注册 帮助
  • 用汇编和VC++混合编程实现API调用情况日志 [已结贴,结贴人:robotom]
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2007-12-17 22:40:36 楼主
    以 comdlg32.dll中的GetSaveFileNameA函数为例。

    基本思路是在FakeDlg32.dll这个DLL中导出MyGetSaveFileNameA函数,
    在MyGetSaveFileNameA中调用comdlg32.dll中的GetSaveFileNameA函数。

    代码如下(本人是汇编门外汉):

    void  __declspec(dllexport) __declspec(naked)  MyGetSaveFileNameA()
    {
        //在函数调用前作一个时间统计
    __asm pushad;
    DLL_LOG_BEGIN(c_function_items ,  DFI_GetSaveFileNameA); 
    __asm popad;

          //取得原始的返回地址
    __asm push ebx;
    __asm mov  ebx , [esp+4];
    __asm mov  old_return[DFI_GetSaveFileNameA], ebx;
    __asm pop ebx;
    __asm add  esp, 4;


          //调用原始的comdlg32.dll中的API
    __asm call GetSaveFileNameA;

            //调用完毕,作时间统计
    __asm  pushad;
    DLL_LOG_END( c_function_items , DFI_GetSaveFileNameA );
    __asm  popad;

            //处理完毕,跳转到原始返回地址。
    __asm jmp  old_return[DFI_GetSaveFileNameA];

    }


    50  修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2007-12-17 22:43:251楼 得分:0
    我的问题:

    >>_asm  call  GetSaveFileNameA;
    这里改为 类似 __asm call  c_function_items[DFI_GetSaveFileNameA].originaladdress;
    时会出错?


    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • alan001
    • 等级:
    发表于:2007-12-18 09:23:252楼 得分:10
    是函数指针吗?
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2007-12-18 09:54:213楼 得分:0
    c_function_items是一个结构体的数组。

    struct FUNCTION_ITEM {
      long  originaladdress;

    } c_function_items[5];

    DFI_GetSaveFileNameA是一个enum常量。


    :是否c_function_items[DFI_GetSaveFileNameA].originaladdress这种写法会改变寄存器的值, 尤其是eax或ecx?

    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2007-12-18 09:58:304楼 得分:0
    其实__asm  jmp    old_return[DFI_GetSaveFileNameA]; 语句如果修改为下面的形式, 貌似也有问题。

    __asm  mov eax ,  offset c_function_items[DFI_GetSaveFileName];
    __asm  jmp [eax];

    请熟悉汇编的哥们帮忙。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2007-12-18 10:08:125楼 得分:0
    可能上面描述的不清楚
    总的目的是想实现这个功能:

    比如 Caller.DLL 调用了 Some.DLL中的  FunctionA 这个函数, 现在想统计Caller.DLL对FunctionA的调用情况,
    于是实现一个新的SomeProxy.DLL, 也实现FunctionA这个函数;然后将Caller.DLL中对Some.DLL的引入项改为SomeProxy.DLL, 这样 调用会被传递到SomeProxy.DLL中来。

    Caller.DLL:
      SomeFunction()
      {
        call  FunctionA@SomeProxy.DLL
        NextStatement: XXXXX
      }

    SomeProxy.DLL:
      FunctionA()
      {
        call  Log_Function_Begin(); 
        Save  return Address to  old_return; //希望保存的值为NextStatement处的地址。
        call  FunctionA@Some.DLL
        call  Log_Function_End();
        jmp  old_return;  //希望能跳转到上面的NextStatement处。
      }
     


     
     

    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • mydo
    • 等级:
    发表于:2007-12-18 10:55:586楼 得分:40
    使用 RDTSC 指令,可以满足你要求。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2007-12-18 11:13:067楼 得分:0
    为什么在有些地方使用结构体就会出错?
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • mydo
    • 等级:
    发表于:2007-12-18 14:11:268楼 得分:0
    把要跳转的地址放在寄存器中然后再跳,譬如:

    mov eax,someobj.someelement

    jmp eax
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2007-12-18 15:42:399楼 得分:0
    根据操作结构体部分对应的汇编代码看,没发现什么很特别的代码,只是使用了eax寄存器。因此可以猜想是否是这种结构体的写法破坏了寄存器。
    假如这个函数使用寄存器eax传递参数或返回值( : win32 API 似乎喜欢依靠这个传递返回值? )
    修改 删除 举报 引用 回复

    网站简介广告服务网站地图帮助联系方式诚聘英才English 问题报告
    世纪乐知(北京)网络技术有限公司 版权所有 京 ICP 证 020026 号
    Copyright © 2000-2007, CSDN.NET, All Rights Reserved