有趣的记忆钩中的符号

时间:2013-01-15 07:36:51

标签: c memory hook

  

可能重复:
  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); 

我猜,这不是一种非常安全的玩记忆方式,但作者评价为“不重要”:

  

像钩子这样的重要代码以代码段形式折叠,但随意   以您喜欢的方式展开和格式化代码。

P.S。如果谷歌已经阻止了“谷歌的乐趣”本身(如果有人有兴趣测试)。

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

关于安全MSDN说 -

  

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

2 个答案:

答案 0 :(得分:5)

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

#define foo(c) c##_

使用foo(bar)调用时,会扩展为bar_

答案 1 :(得分:2)

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