这很可能是以前问过和回答过的,但我的搜索是徒劳的。
问题是位、字节掩码和检查。
假设一个有两个“触发器”0xC40xC5

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
        ...
}

持有一个长数组:
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" },
  ...

这将是一个典型的使用实例。再次重申:这方面的方法。一直在寻找Karnaugh map等-但认为有其他方法等,为同一地区的业务。

最佳答案

考虑到你的两个价值观,

196: 1100 0100  0xc4
197: 1100 0101  0xc5

您需要屏蔽不同的位,在本例中是位0。所以掩码值应该是0x01,0xFE的倒数。
即0xC4&0xFE==0xC4,以及0xC5&0xFE==0xC4。
这意味着两个值都变为0xC4。然后,可以使用应该保留的确切位模式执行异或操作来检查0xC4。
     1100 0100  0xC4

即0xC4^0xC4==0。
     1100 0100    1100 0101
   & 1111 1110    1111 1110
     ---- ----    ---- ----
     1100 0100    1100 0100
   ^ 1100 0100
     ---- ----
     0000 0000

先戴上面具,否则会有完全混乱的危险。
从实际情况来看,我觉得他是想搞糊涂。许多函数需要因子分解。

关于c - 形成和检查位掩码的方法,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/17487121/

10-11 21:24