Can';t在Python中重现工作的C位编码函数

Can';t在Python中重现工作的C位编码函数,python,security,python-2.7,encoding,reverse-engineering,Python,Security,Python 2.7,Encoding,Reverse Engineering,我正在反向工程一个专有的网络协议,它在发射时生成一个(静态)一次性pad,然后使用它对发送/接收的每个数据包进行编码/解码。它在一系列复杂的异或、移位和乘法中使用一次性pad 在使用IDA遍历程序中的解码函数后,我生成了以下C代码。此功能完美地编码/解码数据: void encodeData(char *buf) { int i; size_t bufLen = *(unsigned short *)buf; unsigned long entropy = *((unsi

我正在反向工程一个专有的网络协议,它在发射时生成一个(静态)一次性pad,然后使用它对发送/接收的每个数据包进行编码/解码。它在一系列复杂的异或、移位和乘法中使用一次性pad

在使用IDA遍历程序中的解码函数后,我生成了以下C代码。此功能完美地编码/解码数据:

void encodeData(char *buf)
{
    int i;
    size_t bufLen = *(unsigned short *)buf;
    unsigned long entropy = *((unsigned long *)buf + 2);
    int xorKey = 9 * (entropy ^ ((entropy ^ 0x3D0000) >> 16));
    unsigned short baseByteTableIndex = (60205 * (xorKey ^ (xorKey >> 4)) ^ (668265261 * (xorKey ^ (xorKey >> 4)) >> 15)) & 0x7FFF;

    //Skip first 24 bytes, as that is the header
    for (i = 24; i <= (signed int)bufLen; i++)
        buf[i] ^= byteTable[((unsigned short)i + baseByteTableIndex) & 2047];
}
我尝试过在各种变量上使用和不使用
array()
pack()
/
unpack()
来强制它们成为按位操作的正确大小,但我肯定遗漏了一些东西,因为我无法让Python代码像C代码那样工作。有人知道我错过了什么吗

如果您可以在本地尝试此操作,以下是一次性pad生成函数:

def buildXorPad():
    global xorPad
    xorKey = array('H', [0xACE1])
    for i in range(0, 2048):
        xorKey[0] = -(xorKey[0] & 1) & 0xB400 ^ (xorKey[0] >> 1)
        xorPad = xorPad + pack('B',xorKey[0] & 0xFF)
这是十六进制编码的原始(编码)和解码数据包

原件:
20000108FCF3D71D98590000000000000000000000A992E0EE2525A5E5

解码:
20000108FCF3D71D9859000000000000000000000000000000AE91E1EE25252525

解决方案 事实证明,我的问题与C和Python类型之间的差异无关,而是与一些简单的编程错误有关

def encodeData(buf):
    newBuf = bytearray(buf)
    bufLen = unpack('H', buf[:2])
    entropy = unpack('I', buf[8:12])
    xorKey = 9 * (entropy[0] ^ ((entropy[0] ^ 0x3D0000) >> 16))
    baseByteTableIndex = (60205 * (xorKey ^ (xorKey >> 4)) ^ (668265261 * (xorKey ^ (xorKey >> 4)) >> 15)) & 0x7FFF;
    #Skip first 24 bytes, since that is header data
    for i in range(24,bufLen[0]):
        padIndex = (i + baseByteTableIndex) & 2047
        newBuf[i] ^= unpack('B',xorPad[padIndex])[0]
    return str(newBuf)
谢谢大家的帮助

这行C:

unsigned long entropy = *((unsigned long *)buf + 2);
应该翻译成

entropy = unpack('I', buf[8:12])
因为在向地址添加2之前,
buf
首先被强制转换为无符号长,这会向地址添加2个无符号长的大小,而不是2个字节(假设无符号长的大小为4个字节)

此外:

应该是

newBuf[i] ^= xorPad[(i + baseByteTableIndex) & 2047]

要匹配C,否则输出实际上并不基于缓冲区的内容。

Python整数不会溢出-当它们超过sys.maxint(或
-sys.maxint-1
)时,会自动提升到任意精度

使用
array
和/或
unpack
似乎没有什么区别(正如您所发现的)


要截断数字,您必须在增加变量大小时手动使用适当的位掩码进行ANDing,以模拟溢出。

解码的数据几乎与原始数据相同-是吗?是的,我应该在代码中添加更多注释。前24个字节是未编码的标头。我特别选择了这个数据包,因为“有效负载”减去报头的长度只有8个字节,并且我知道最后4个字节在解码时应该是0x25252525。首先,我会将所有计算屏蔽到正确的位长度,并确定是否需要逻辑或算术移位,并将其显式化。XORing是指ANDing吗?我也尝试过使用位掩码进行ANDing,但我会再试一次,确保捕获所有需要屏蔽的案例。@k0ss,是的,很抱歉,我会修复postpvoted,因为虽然我已经尝试过,但对于需要人为限制变量大小的人来说,这是一个很好的建议。好的,您已经了解了一些内容。我真不敢相信我错过了,我抓错了信息包的熵值部分!我甚至有一个010编辑器模板显示了它的位置,但显然忽略了它。问题是它仍然不起作用。这可能是endian ness的问题,我会在早上尝试解决。谢谢,解决了!我想这只是一些简单的编程错误,而不是编码/类型问题。我需要更加小心!我把最终的编码函数发布在主帖子中。
newBuf[i] = xorPad[(i + baseByteTableIndex) & 2047]
newBuf[i] ^= xorPad[(i + baseByteTableIndex) & 2047]
>>> sys.maxint
9223372036854775807
>>> sys.maxint + 1
9223372036854775808L
>>> array('H', [1])[0] + sys.maxint
9223372036854775808L
>>> unpack('H', '\x01\x00')[0] + sys.maxint
9223372036854775808L