这很可能之前已被问及并得到解答,但我的搜索是徒劳的。
问题是关于位,字节掩码和检查。
假设有一个“触发器” 0xC4
和0xC5
:
196: 1100 0100 0xc4 197: 1100 0101 0xc5
检查var
是否为的简单方法是:
if (var == 0xc5 || var == 0xc4) { }
但有时人们会看到这个(或类似的):
if ( ((var ^ magic) & mask) == 0) { }
我的问题是如何找到魔法和面具 。 使用哪些方法,程序,技巧等来形成这些值并断言是否存在?
编辑:
澄清。 是的,在这个确切的例子中,前者会比后者更好,但我的问题更像是生成和检查这些类型的掩码。 总的来说有点笨拙。 我省略了很多,并试图使问题变得简单。 但……
作为一个例子,我看了一下OllyDbg反编译源的来源,其中一个发现:
if (((code ^ pd->code) & pd->mask) == 0) FOUND
其中code
是0-3个字节的命令来自指令。
unsigned long code = 0; if (size > 0) *(((char *)&code) + 0) = cmd[0]; if (size > 1) *(((char *)&code) + 1) = cmd[1]; if (size > 2) *(((char *)&code) + 2) = cmd[2];
如在屏蔽仅cmd
字节部分
pd
是以下内容的一部分:
struct t_cmddata { uint32_t mask; Mask for first 4 bytes of the command uint32_t code; Compare masked bytes with this ... }
持有一个长arrays:
const t_cmddata cmddata[] = { /* mask code */ { 0x0000FF, 0x000090, 1,00, NNN,NNN,NNN, C_CMD+0, "NOP" }, { 0x0000FE, 0x00008A, 1,WW, REG,MRG,NNN, C_CMD+0, "MOV" }, { 0x0000F8, 0x000050, 1,00, RCM,NNN,NNN, C_PSH+0, "PUSH" }, { 0x0000FE, 0x000088, 1,WW, MRG,REG,NNN, C_CMD+0, "MOV" }, { 0x0000FF, 0x0000E8, 1,00, JOW,NNN,NNN, C_CAL+0, "CALL" }, { 0x0000FD, 0x000068, 1,SS, IMM,NNN,NNN, C_PSH+0, "PUSH" }, { 0x0000FF, 0x00008D, 1,00, REG,MMA,NNN, C_CMD+0, "LEA" }, { 0x0000FF, 0x000074, 1,CC, JOB,NNN,NNN, C_JMC+0, "JE,JZ" }, { 0x0000F8, 0x000058, 1,00, RCM,NNN,NNN, C_POP+0, "POP" }, { 0x0038FC, 0x000080, 1,WS, MRG,IMM,NNN, C_CMD+1, "ADD" }, { 0x0000FF, 0x000075, 1,CC, JOB,NNN,NNN, C_JMC+0, "JNZ,JNE" }, { 0x0000FF, 0x0000EB, 1,00, JOB,NNN,NNN, C_JMP+0, "JMP" }, { 0x0000FF, 0x0000E9, 1,00, JOW,NNN,NNN, C_JMP+0, "JMP" }, { 0x0000FE, 0x000084, 1,WW, MRG,REG,NNN, C_CMD+0, "TEST" }, { 0x0038FE, 0x0000C6, 1,WW, MRG,IMM,NNN, C_CMD+1, "MOV" }, { 0x0000FE, 0x000032, 1,WW, REG,MRG,NNN, C_CMD+0, "XOR" }, ...
这将是一个典型的实际使用示例。 再说一次:方法。 一直在看卡诺图等 – 但是想到了同一区域的其他等方法。
鉴于你的两个价值观,
196: 1100 0100 0xc4 197: 1100 0101 0xc5
你想要掩盖不同的位,在这种情况下是位0.因此掩码值将是0x01的倒数,0xFE。
即。 0xC4&0xFE == 0xC4,以及0xC5&0xFE == 0xC4。
这意味着两个值都变为0xC4。 然后你可以通过xor -ing检查0xC4与应该保留的确切位模式。
1100 0100 0xC4
即。 0xC4 ^ 0xC4 == 0。
1100 0100 1100 0101 & 1111 1110 1111 1110 ---- ---- ---- ---- 1100 0100 1100 0100 ^ 1100 0100 ---- ---- 0000 0000
首先掩盖,或冒险完全混乱。
通过实际的源文件 ,我认为他正在试图被混淆。 许多function都需要保理。
我假设您的问题是:给定一组“触发器”,我们可以找到一个掩码和魔法,可以通过以下代码检查触发器
if ( ((var ^ magic) & mask) == 0) { }
或者它是一样的
if ((var & mask) == (magic & mask)) { }
“触发器”的一个例子就像
196: 1100 0100 0xc4 197: 1100 0101 0xc5 204: 1100 1100 0xcc 205: 1100 1101 0xcd
如果可行,则“触发器”的位应分为2种类型:“特定位”和“任意位”。 与前4位,第6位和第7位一样,每个触发中的特定位相同。 如果你改变一个触发器的任意位,它仍然是一个触发器。
因此恰好有2 ^ N个触发器,其中N表示任意位的数量。
这是我在stackoverflow上的第一个答案。 我不确定我是否正确理解你的问题。 或者你在问其他有点混乱的方法?
以上就是c/c++开发分享形成和检查位掩码的方法相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/c-cdevelopment/562493.html