出現使用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() - > ...
現在讓我們來看看evahash。我們非常幸運,因爲官方網站https://oss.oracle.com/projects/ocfs-tools/src/branches/new-dir-format/libocfs/Linux/inc/ocfshash.h上有一個頭文件,帶有evahash鏈接。
終於有實際的C代碼頁http://burtleburtle.net/bob/hash/evahash.html
到目前爲止好,我們記得,我們可以使用外部的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。
我希望這很有趣。祝你好運。
更新
ora_hash和dbms_utility.get_hash_value可以映射到對方(見https://jonathanlewis.wordpress.com/2009/11/21/ora_hash-function/)
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
。也許我會在明年花一些時間。
如果您想重新實現以調用無法訪問真實數據庫的應用程序,爲什麼需要重新實現'ORA_HASH'?這有什麼神奇的?編寫你自己的簡單散列函數,不要參考'ORA_HASH'。 – mathguy
這裏的關鍵詞是「撥打另一個系統的服務電話」。如果我使用不同的算法,我會得到不同的哈希值,並且調用不起作用。 –
哦......我明白了; 「似乎使用'ORA_HASH'」的「其他系統」不受你控制。我的觀點是,使用你在兩者中創建的相同功能;但如果你只控制一方,我明白你爲什麼需要這個。 – mathguy