标签: detours

Microsoft Detours如何工作以及如何使用它来获取堆栈跟踪?

我是微软Detours的新手.我已经安装它来跟踪进程所做的系统调用.我运行以下来自网络的命令

syelogd.exe /q C:\Users\xxx\Desktop\log.txt 
withdll.exe /d:traceapi.dll C:\Program Files\Google\Google Talk\googletalk.exe
Run Code Online (Sandbox Code Playgroud)

我得到了日志文件.问题是我不完全理解这里发生了什么.弯路如何运作?它如何跟踪系统调用?另外我不知道如何读取log.txt中的输出.这是log.txt中的一行

20101221060413329 2912 50.60: traceapi: 001 GetCurrentThreadId()
Run Code Online (Sandbox Code Playgroud)

最后,我想获得该过程的堆栈跟踪.我怎么能得到它?

windows detours

21
推荐指数
3
解决办法
2万
查看次数

为商业应用程序挂钩Win32 API的推荐方法是什么?

您对API挂钩库或商业应用程序中使用的代码的建议是什么?

我看过微软Detours,看起来非常好,但绝对超出预算,我期待从我的应用程序中获利.

是否有任何库可以提供WinXP和Vista之间的兼容性(如果不是太多问题,可以提供Windows 7)?有没有过在商业产品中使用这种库的经验的人?

api hook winapi detours

8
推荐指数
2
解决办法
1万
查看次数

绕行和GCC内联汇编(Linux)

我正在为一个为(我们)modders提供API的游戏编程扩展.这个API提供了各种各样的东西,但它有一个限制.API仅用于"引擎",这意味着基于引擎发布的所有修改(mod)都不提供/具有任何类型的(特定于mod)API.我创建了一个'签名扫描程序'(注意:我的插件是作为共享库加载的,用-share&-fPIC编译),它找到了感兴趣的函数(这很简单,因为我在linux上).所以要解释一下,我将采取一个具体的案例:我已经找到了一个感兴趣的函数的地址,它的函数头很简单int * InstallRules(void);.它不需要任何东西(void)并返回一个整数指针(对我感兴趣的对象).现在,我想要做的是创建一个绕行(并记住我有函数的起始地址),对我自己的函数,我想表现如下:

void MyInstallRules(void)
{
    if(PreHook() == block) // <-- First a 'pre' hook which can block the function
        return;
    int * val = InstallRules(); // <-- Call original function
    PostHook(val); // <-- Call post hook, if interest of original functions return value
}
Run Code Online (Sandbox Code Playgroud)

现在这是交易; 我没有任何关于功能挂钩的经验,而且我对内联汇编(仅限AT&T)知之甚少.互联网上预先制作的绕行程序包适用于Windows或使用其他整个方法(即预加载dll以覆盖原始程序).所以基本上; 我该怎么办才能走上正轨?我应该阅读有关调用约定(在本例中为cdecl)并了解内联汇编或该怎么做?最好的可能是linux绕行的功能性封装类.最后,我想要一些简单的事情:

void * addressToFunction = SigScanner.FindBySig("Signature_ASfs&43"); // I've already done this part
void * original = PatchFunc(addressToFunction, addressToNewFunction); // This replaces the original function with a hook to mine, …
Run Code Online (Sandbox Code Playgroud)

linux assembly hook gcc detours

8
推荐指数
1
解决办法
1468
查看次数

需要从绕行功能调用原始功能

我正在使用Detours挂钩到可执行文件的消息函数,但我需要运行自己的代码然后调用原始代码.从我在Detours文档中看到的内容来看,这听起来应该是自动发生的.原始功能会在屏幕上显示一条消息,但是一旦我附上绕道,就会开始运行我的代码并停止打印.

原始功能代码大致是:

void CGuiObject::AppendMsgToBuffer(classA, unsigned long, unsigned long, int, classB);
Run Code Online (Sandbox Code Playgroud)

我的功能是:

void CGuiObject_AppendMsgToBuffer( [same params, with names] );
Run Code Online (Sandbox Code Playgroud)

我知道原始函数所在的内存位置,因此使用:

DWORD OrigPos = 0x0040592C;
DetourAttach( (void*)OrigPos, CGuiObject_AppendMsgToBuffer);
Run Code Online (Sandbox Code Playgroud)

让我进入这个功能.这段代码几乎完美无缺:用适当的参数调用我的函数.但是,执行会离开我的函数并且不会调用原始代码.我已经尝试过jmping,但是崩溃了程序(我假设代码Detours移动以适应钩子负责崩溃).

编辑:我已设法修复第一个问题,没有返回程序执行.通过将OrigPos值作为函数调用,我可以转到"trampoline"函数并从那里到原始代码.但是,在某些地方,寄存器正在发生变化,一旦我回到原始代码,就会导致程序崩溃并出现段错误.

Edit2:最终工作代码:

class CGuiObject
{
 public:
    void MyFunc( [params] );
};

DWORD TrueAddr = 0x0040592C;

CGuiObject::MyFunc( [params] )
{
    _asm { pushad }
    // process
    _asm {
        popad
        leave
        jmp TrueAddr
    }
}
Run Code Online (Sandbox Code Playgroud)

并使用TrueAddr作为DetourAttach中的第一个参数.

c++ hook detours

6
推荐指数
0
解决办法
2224
查看次数

微软Detours - DetourUpdateThread?

我有一些关于Microsoft Detours Library的快速问题.我之前(成功)使用过它,但我只是想到了这个功能:

LONG DetourUpdateThread(HANDLE hThread);

我在别处读到这个函数实际上会挂起线程,直到事务完成.由于大多数示例代码调用,这似乎很奇怪

DetourUpdateThread(GetCurrentThread());

无论如何,显然这个函数"登记"线程,以便当事务提交(并且绕道而行)时,如果它们位于"目标函数或蹦床函数中的重写代码内",则修改它们的指令指针.

我的问题是:

当事务提交时,当前线程的指令指针是否在DetourTransactionCommit函数内?如果是这样,我们为什么要打扰它进行更新呢?

此外,如果登记的线程被挂起,当前线程如何继续执行(假设大多数示例代码调用DetourUpdateThread(GetCurrentThread());)?

最后,您是否可以暂停当前进程的所有线程,避免竞争条件(考虑到线程可能随时被创建和销毁)?也许这是在交易开始时完成的?这将允许我们更安全地枚举线程(因为似乎不太可能创建新线程),尽管CreateRemoteThread()怎么样?

谢谢,

保罗

作为参考,这里是简单样本的摘录:

// DllMain function attaches and detaches the TimedSleep detour to the
// Sleep target function.  The Sleep target function is referred to
// through the TrueSleep target pointer.
BOOL WINAPI DllMain(HINSTANCE hinst, DWORD dwReason, LPVOID reserved)
{
    if (dwReason == DLL_PROCESS_ATTACH) {
        DetourTransactionBegin();
        DetourUpdateThread(GetCurrentThread());
        DetourAttach(&(PVOID&)TrueSleep, TimedSleep);
        DetourTransactionCommit();
    }
    else if (dwReason == DLL_PROCESS_DETACH) {
        DetourTransactionBegin();
        DetourUpdateThread(GetCurrentThread());
        DetourDetach(&(PVOID&)TrueSleep, TimedSleep);
        DetourTransactionCommit();
    }
    return TRUE;
}
Run Code Online (Sandbox Code Playgroud)

c++ windows multithreading detours

6
推荐指数
1
解决办法
2599
查看次数

Detours替代Registry拦截

我正在寻找一种方法来拦截和重定向读取到某些注册表项.当然,Detours可以做到这一点.但我需要它用于商业应用,而MS $ 10K的许可证费用有点过于陡峭.还有其他选择吗?

windows registry winapi detours

6
推荐指数
1
解决办法
1783
查看次数

Detours Hook在外部进程中为"空"功能不起作用

我通过它们的函数偏移在外部进程中挂钩函数.这对于我到目前为止挂钩的函数效果很好 - 但是我发现了一个"debugLog(char ...)"函数,它仍然存在于二进制文件中但没有进行任何打印 - 它看起来像这样

debugMessage    proc near               ; 
            xor     eax, eax        ; Logical Exclusive OR
            retn                    ; Return Near from Procedure
debugMessage    endp
Run Code Online (Sandbox Code Playgroud)

它被称为这样

push    offset debugString ; "This is a debug message"...
call    debugMessage    ; Call Procedure
Run Code Online (Sandbox Code Playgroud)

现在调试消息显然已被禁用,我想挂钩到这个,因为我能够简单地挂钩到二进制文件中的类似func(char ..).

这是代码:

typedef void (__stdcall* DebugLog)(const char*);
DebugLog Real_DebugLog = (DebugLog)(0xCAFEBABE);

extern "C"
 {
 static void __stdcall Hook_DebugLog(const char*);
 }

void __stdcall Hook_DebugLog(const char* text) {
MessageBox(NULL, text, "MyDebugLog", MB_OK);
return Real_DebugLog(text);
}

// in dll main attach..
DetourTransactionBegin(); …
Run Code Online (Sandbox Code Playgroud)

c++ assembly detours

6
推荐指数
1
解决办法
1148
查看次数

C++和FULLY动态函数

我有一个绕道而行的问题.众所周知,Detours只能在5个字节的空间中移动(即'jmp'调用和4字节地址).因此,不可能在类(方法)中使用'hook'函数,你不能提供'this'指针,因为没有足够的空间(这里的问题得到了更彻底的解释).所以我整天都在集思广益寻找解决方案,现在我想要你对这个主题的想法,所以我不会在不知道是否可能的情况下开始3-5天的项目.

我最初有3个目标,我希望'hook'函数是类方法,我希望整个方法是面向对象的(没有静态函数或全局对象),而最坏/最难的部分是完全动态的.这是我的(理论上)解决方案; 使用程序集可以在运行时修改函数(一个完美的例子是任何绕行方法).因为我可以动态修改函数,我不应该也能动态创建它们吗?例如; 我分配内存,比方说~30个字节(通过malloc/new).是不是可以用对应于不同汇编运算符的二进制数替换所有字节(如0xE9是'jmp')然后直接调用地址(因为它将包含一个函数)?

注意:我事先知道返回值,以及我想要绕道的所有函数的所有参数,并且因为我使用GCC,所以thiscall约定实际上与_cdecl约定相同.

所以这是我的想法/即将实施; 我创建了一个'Function'类.此构造函数采用可变量的参数(第一个参数除外,它描述了目标函数的返回值).

每个参数都是钩子将接收的参数的描述(大小,以及它是否是指针).所以我想说我想为一个创建一个Function类int * RandomClass::IntCheckNum(short arg1);.然后我就必须这样做:Function func(Type(4, true), Type(4, true), Type(2, false));.其中'类型'定义为Type(uint size, bool pointer).然后通过程序集我可以动态创建函数(注意:这将全部使用_cdecl调用约定),因为我可以计算参数的数量和总大小.

编辑:对于示例,Type(4, true)是返回值(int*),scond Type(4, true)是RandomClass'this'指针并Type(2, false)描述第一个参数(简短arg1).

通过这个实现,我可以很容易地将类方法作为回调,但是它需要大量的汇编代码(我甚至没有特别经验).最后,唯一非动态的东西就是我的回调类中的方法(也需要前后回调).

所以我想知道; 这可能吗?它需要多少工作,我是否在这里?

编辑:我很抱歉,如果我把所有东西都弄得有些模糊,但是如果你想要更全面的解释,请问!

EDIT2:我还想知道,如果我能在某处找到所有汇编运算符的十六进制值?一份清单会有所帮助!和/或如果有可能以某种方式"保存"asm(""); 代码在内存地址(我非常怀疑).

c++ assembly detours this cdecl

6
推荐指数
1
解决办法
859
查看次数

使用 C++ 挂钩 GetTickCount

我不太擅长 C++,更擅长 C# 和 PHP。我被分配了一个项目,需要我使用GetTickCount并连接到一个应用程序。我需要一些帮助,因为由于某种原因它没有按计划工作...这是挂钩的代码,我知道它有效,因为我以前在项目中使用过它。我唯一不太确定的是GetTickCount它的一部分。我尝试GetTickCount64认为这可以解决我的问题(它没有使我注入的内容崩溃),但发现它根本不起作用,所以它没有崩溃。

bool APIENTRY DllMain(HINSTANCE hDll, DWORD dwReason, LPVOID lpReserved)
{
 switch(dwReason)
 {
 case DLL_PROCESS_ATTACH:

  DisableThreadLibraryCalls(hDll);
  CreateThread(0,0, (LPTHREAD_START_ROUTINE)KeyHooks, 0, 0, 0);
  GetTickCount_orig = (DWORD (__stdcall *)(void))DetourFunction((PBYTE)GetProcAddress(GetModuleHandle("kernel32.dll"), "GetTickCount"), (PBYTE)GetTickCount_hooked);

 case DLL_PROCESS_DETACH:
  DetourRemove((PBYTE)GetProcAddress(GetModuleHandle("kernel32.dll"), "GetTickCount"), (PBYTE)GetTickCount_hooked);

  break;
 }
 return true;
}
Run Code Online (Sandbox Code Playgroud)

这是用于的其余代码GetTickCount

DWORD oldtick=0;
DWORD (WINAPI *GetTickCount_orig)(void);
DWORD WINAPI GetTickCount_hooked(void)
{ 
 if(oldtick==0)
 {
  oldtick=(*GetTickCount_orig)();
  return oldtick;
 }
 DWORD factor;
 DWORD ret;

 ret = (*GetTickCount_orig)();
 factor = 3.0;
 DWORD newret;

 newret = ret+((oldtick-ret)*(factor-1));

 oldtick=ret; …
Run Code Online (Sandbox Code Playgroud)

c++ hook winapi detours gettickcount

5
推荐指数
1
解决办法
3786
查看次数

在 C# 中运行时挂钩托管方法

我有一个密封类,在程序集中有一个公共方法,我想添加一个日志系统,但不幸的是我没有源代码。因此,我尝试在特定的日志记录方法上绕过此方法,并在退出时调用原始方法。挂钩工作正常,但我无法获取任何类型的参数,或者至少我得到了完全错误的东西。

我也不能使用任何类型的注入或像 PostSharp 这样的库,所以我想知道这种东西是否可以在运行时以某种方式实现,或者我可以放弃吗?

为了给您提供更多详细信息,我将在下面粘贴一些代码部分:

public Hook(Delegate target, Delegate hook)
{
  this.target = Marshal.GetFunctionPointerForDelegate(target);
  targetDelegate = target;
  this.hook = Marshal.GetFunctionPointerForDelegate(hook);

  originalBytes = new byte[6];
  Marshal.Copy(this.target, originalBytes, 0, 6);

  byte[] hookPointerBytes = BitConverter.GetBytes(this.hook.ToInt32());
  // Jump
  newBytes = new byte[]
  {
    0x68, hookPointerBytes[0], hookPointerBytes[1], hookPointerBytes[2], hookPointerBytes[3], 0xC3
  };
}

public object CallOriginal(params object[] args)
{
  // Remove the patch
  Uninstall();
  // Invoke the original method
  object ret = targetDelegate.DynamicInvoke(args);
  // Re-apply the patch
  Install();
  return ret;
}


public sealed class Foo
{ …
Run Code Online (Sandbox Code Playgroud)

c# methods hook detours managed

5
推荐指数
1
解决办法
7240
查看次数

标签 统计

detours ×10

c++ ×5

hook ×5

assembly ×3

winapi ×3

windows ×3

api ×1

c# ×1

cdecl ×1

gcc ×1

gettickcount ×1

linux ×1

managed ×1

methods ×1

multithreading ×1

registry ×1

this ×1