【问题标题】:Notation in interesting memory hook [duplicate]有趣的记忆挂钩中的符号[重复]
【发布时间】:2013-01-15 07:36:50
【问题描述】:

可能重复:
What is the use of ## preprocessor in C

来自Fun with Google TTS ... 任何人都可以阐明这段代码是如何工作的?特别是 - “c##_”是什么符号? -

#define DsHook(a,b,c) if (!c##_) { 
INT_PTR* p=b+*(INT_PTR**)a;  VirtualProtect(&c##_,4,PAGE_EXECUTE_READWRITE,&no);
*(INT_PTR*)&c##_=*p;  VirtualProtect(p,4,PAGE_EXECUTE_READWRITE,&no);  *p=(INT_PTR)c;

它在代码中展开为 -

//  redirect  7th member func of IAsyncReader (SyncReadAlligned) to grab mp3 data from output pin of source filter
DsHook(reader,6,SyncReadAlligned); 

我猜,玩记忆的方式不是很安全,但被作者评论为“不重要”:

像钩子这样不重要的代码被折叠成 sn-p 形式,但可以随意 以您喜欢的方式展开和格式化代码。

附: “Fun with Google”本身(如果已被 Google 屏蔽)(如果有人有兴趣测试)。

更新:我认为,简短的分析应该是 - 为了“重定向 IAsyncReader (SyncReadAlligned) 的第 7 个成员函数以从源过滤器的输出引脚获取 mp3 数据”,我们将已提交页面的某些区域的内存保护从“无论它是什么”更改为 PAGE_EXECUTE_READWRITE(允许完全访问)。

关于安全性 MSDN 说 -

最好避免使用 VirtualProtect 来更改页面保护 由 GlobalAlloc、HeapAlloc 或 LocalAlloc 分配的内存块, 因为单个页面上可以存在多个内存块。 ... 当保护一个可执行的区域时,调用程序 负责确保缓存一致性...

【问题讨论】:

  • 谷歌搜索并在堆栈溢出时搜索##。但我对这段代码的工作方式也很感兴趣。

标签: c memory hook


【解决方案1】:

这是一个预处理指令,意思是“连接”。 c##_ 将生成一个包含参数 c 的替换值和文字字符 _ 的标记。示例:

#define foo(c) c##_

当使用foo(bar) 调用时,它将扩展为bar_

【讨论】:

  • 谢谢,这么想,但不确定。有没有关于这个钩子安全的cmets?
【解决方案2】:

这种符号## 在宏定义中具有特殊含义,即连接。这里c##_将c与下划线连接起来形成一个新的标记c_。注意这里 c 是一个参数。因此,通过将hereIAm 作为参数传递给宏,扩展后c##_ 将变为hereIAm_

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-03
    • 1970-01-01
    • 1970-01-01
    • 2021-12-22
    相关资源
    最近更新 更多