出现使用ORA_HASH
好另一个系统,如果“出现用”它的话很有道理做一点逆向工程的检查究竟是什么叫和拆卸的代码功能。
但是,如果您想要深入Oracle内部,那么以下可能会有所帮助。
首先,你必须弄清楚调用什么内部C函数。 为此,您可以在一个会话中执行一些长时间运行的代码。 我并运行此
select avg(ora_hash(rownum)) id from
(select rownum from dual connect by rownum <= 1e4),
(select rownum from dual connect by rownum <= 1e4);
它可以是PL/SQL代码,以及,你只需要确保你不断地打电话ora_hash。
虽然它的运行
我在Windows上测试过,看起来像ora_hash是...-> evaopn2() - >evahash() - > ...
到目前为止好,我们记得,我们可以使用外部的C函数在Oracle中,如果我们建立成库(DLL在Windows上)。
例如我赢X64的,如果我改变函数签名
extern "C" ub4 hash(ub1 *k, ub4 length, ub4 initval)
它可以从Oracle成功执行。 但是,如您所见,签名有点不同于Oracle中的ora_hash。该函数接受值,它的长度和initval(可能是种子),而Oracle中的签名是ora_hash(expr,max_bucket,seed_value)。
让我们尝试测试 甲骨文
SQL> select ora_hash(utl_raw.cast_to_raw('0'), power(2, 32) - 1, 0) oh1,
2 ora_hash('0', power(2, 32) - 1, 0) oh2,
3 ora_hash(0, power(2, 32) - 1, 0) oh3,
4 ora_hash(chr(0), power(2, 32) - 1, 0) oh4
5 from dual;
OH1 OH2 OH3 OH4
---------- ---------- ---------- ----------
3517341953 3517341953 1475158189 4056412421
C中的号码匹配的
int main()
{
ub1 ta[] = {0};
ub1* t = ta;
cout << hash(t, 1, 0) << endl;
ub1 ta0[] = {'0'};
ub1* t0 = ta0;
cout << hash(t0, 1, 0) << endl;
return 0;
}
1843378377
4052366646
无。 那么问题是什么? ora_hash接受几乎任何类型的参数(例如select ora_hash(sys.odcinumberlist(1,2,3)) from dual),而C函数接受值作为字节数组。这意味着某些转换发生在函数调用之前。 因此,在使用提到的C哈希函数之前,您必须弄清楚实际值在传递给它之前如何转换。
您可以继续使用IDA PRO + hex射线对Oracle二进制文件进行逆向工程,但这可能需要几天时间。更不用说平台的具体细节。
所以如果你想模仿ora_hash,最简单的选择是安装Oracle express版本并使用它来调用ora_hash。
我希望这很有趣。祝你好运。
更新
SQL> select dbms_utility.get_hash_value('0', 0 + 1, 1e6 + 1) ha1,
2 ora_hash('0', 1e6, 0) + 1 ha2
3 from dual;
HA1 HA2
---------- ----------
338437 338437
如果我们解开DBMS_UTILITY的包体,我们将看到以下声明
function get_hash_value(name varchar2, base number, hash_size number)
return number is
begin
return(icd_hash(name, base, hash_size));
end;
and
function icd_hash(name varchar2,
base binary_integer,
hash_size binary_integer) return binary_integer;
pragma interface(c, icd_hash);
让我们谷歌icd_hash,我们可以发现它被映射到_psdhsh(https://yurichev.com/blog/50/)。现在是时候反汇编oracle.exe并从中提取代码_psdhsh。也许我会在明年花一些时间。