[20261004]oracle sskgph2函数等价c以及python脚本.txt
# bpftrace sskgphpjw.bt 0
Attached 8 probes
sskgpwidtokeys Begin
sskgpbitspersem Begin
[10:21:51] sskgpbitspersem pid=4467 return hash_value=0x0000000e 14
sskgpbitspersem End
[10:21:51] sskgphpjw pid=4467 ptr=0x00007ffdd9d1c260 len=43 str=book/u01/app/oracle/product/21.0.0/dbhome_1
[10:21:51] sskgphpjw pid=4467 return hash_value=0x5507207c 1426530428
[10:21:51] sskgphpjw pid=4467 ptr=0x00007ffdd9d1c260 len=43 str=cppl0v120bqq0psbdmf0qspevdu032/1/10ecipnf2
[10:21:51] sskgphpjw pid=4467 return hash_value=0x7e0edb60 2114902880
[10:21:51] sskgphpjw pid=4467 ptr=0x00007ffdd9d1c260 len=43 str=dqqm1w231crr1qtceng1rtqfwev14302021fdjqoga3
[10:21:51] sskgphpjw pid=4467 return hash_value=0x99eaaedc 2582294236
[10:21:51] sskgphpjw pid=4467 ptr=0x00007ffdd9d1c260 len=43 str=errn2x342dss2rudfoh2surgxfw25413132gekrphb4
[10:21:51] sskgphpjw pid=4467 return hash_value=0x32fcf5bc 855438780
sskgph2 Begin
[10:21:51] sskgph2 pid=4467 return hash_value=0x9937c3fd 2570568701
sskgph2 End
sskgpwidtokeys End
--//Python脚本如下:
python
def sskgph2(data: bytes) -> int:
state = [0, 0, 0, 0]
rdx = 0
n = len(data)
for i in range(n // 2):
state[rdx] = ((state[rdx] << 1) & 0xFF) ^ data[2*i]
rdx = (rdx + 1) & 3
state[rdx] = ((state[rdx] << 1) & 0xFF) ^ data[2*i + 1]
rdx = (rdx + 1) & 3
if n & 1:
state[rdx] = ((state[rdx] << 1) & 0xFF) ^ data[n - 1]
result = (state[0] << 24) | (state[1] << 16) | (state[2] << 8) | state[3]
return result if result else 1
用:
python
data = b"book/u01/app/oracle/product/21.0.0/dbhome_1"
print(hex(sskgph2(data)))
--//我的计算:
>>> from sskgph2 import sskgph2
>>> data = b"book/u01/app/oracle/product/21.0.0/dbhome_1"
>>> print(hex(sskgph2(data)))
0x9937c3fd
--//c语言脚本:
$ cat sskgph2.c
#include <stdint.h>
#include <stdio.h>
#include <string.h>
/*
* sskgph2 - Oracle 内部共享内存 key 哈希(从反汇编 0x57b5d00 翻译)
*
* 输入结构体布局:
* data[0x00 .. 0xFF] 待哈希的字节序列
* data[0x100 .. 0x107] 8 字节长度(小端)
*
* 返回 32 位大端拼装的哈希值;若结果为 0 则返回 1。
*/
uint32_t sskgph2(const uint8_t *data)
{
uint64_t len = *(const uint64_t *)(data + 0x100);
uint8_t state[4] = {0, 0, 0, 0};
int rdx = 0; /* 状态轮转下标 */
uint64_t half = len / 2;
uint64_t i;
/* 主循环:每次处理 2 个字节 */
for (i = 0; i < half; i++) {
state[rdx] = (uint8_t)((state[rdx] << 1) ^ data[2 * i]);
rdx = (rdx + 1) & 3;
state[rdx] = (uint8_t)((state[rdx] << 1) ^ data[2 * i + 1]);
rdx = (rdx + 1) & 3;
}
/* 奇数长度:多处理最后一个字节 */
if (len & 1) {
state[rdx] = (uint8_t)((state[rdx] << 1) ^ data[len - 1]);
}
/* 打包成 32 位大端值 */
uint32_t result = ((uint32_t)state[0] << 24)
| ((uint32_t)state[1] << 16)
| ((uint32_t)state[2] << 8)
| (uint32_t)state[3];
return result ? result : 1;
}
/* ---------- 测试 ---------- */
int main(int argc, char **argv)
{
const char *s = "book/u01/app/oracle/product/21.0.0/dbhome_1";
if (argc >= 2)
s = argv[1];
size_t len = strlen(s);
/* 构造结构体:数据在 [0x00],长度在 [0x100] */
uint8_t buf[0x108];
memset(buf, 0, sizeof(buf));
memcpy(buf, s, len);
*(uint64_t *)(buf + 0x100) = (uint64_t)len;
uint32_t h = sskgph2(buf);
printf("str = %s\n", s);
printf("len = %zu\n", len);
printf("hash = 0x%08x\n", h);
return 0;
}
$ gcc sskgph2.c -o sskgph2
$ ./sskgph2
str = book/u01/app/oracle/product/21.0.0/dbhome_1
len = 43
hash = 0x9937c3fd
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/267265/viewspace-3184453/ ,如需转载,请注明出处,否则将追究法律责任。