t00x ээээ.... а зачем такие извращения? ) никаких деревьев, дизасм и поиск сигнатуры в заранее известкой экспортируемой ф-ции, которая вызывает искомую.
TSS точно, забыл и не увидел... ohne именно! шикарность в ее очевидности! я думаю этому методу не 100, а целых 1000 лет в обед
По-моему, тут даже дизассемблер не нужен -- можно тупо сравнить по маске, учитывая, что некоторые участки кода могут быть поправлены релокацией. Все равно придется для каждой версии свою маску держать.
Mika0x65 как могут быть поправлены: push var_offset call @procname и небольшой дизасм все же нужен иначе можно напороться на мусор вместо вызова ф-ции...
кстати, какими методами (желательно простыми) можно гарантировать, что вдруг найденная последовательность E8 XX XX XX XX - именно вызов функции, а не кусок какого-то мусора/данных/етц. и на нее стоит обратить внимание?
В смысле, поправлены? Правятся асболютные адреса. Например, в командах 'mov eax, [addr_of_a_variable]'. Код инструкции в этом случае будет 0xA1 XX XX XX XX, байты XX вероятно, будут исправлены загрузчиком (если библиотека загрузилась не по ожидаемому адресу). А в 'push val/call func' ничего исправлено не будет. Если, конечно, это не 'call [addr_of_a_function]'.
а как насчет выравнивания по 4-х байтной границе? т.е. call "что-то там" должен быть быть выровнен по DWORD?
Это не жесткое требование и может зависеть от компилятора/программиста. А стек, да, должен быть выровнен на границу четыре байта, иначе Windows плохеет. По крайней мере в 32битной версии для user mode.
Мммм... Мне кажется, что я чего-то недопонимаю. В чем вопрос вообще? Из самых общих соображений -- берешь, например, RVA некоторой экспортируемой ф-ии, натравливаешь дизассемблер на ее тело. Получаешь размер первой инструкции, увеличиваешь на это значение указатель инструкций, дизассемблируешь следующую инструкцию. И т.д. Ну, и в зависимости от целей -- анализируешь переходы Jcc, вызовы call и прочее. Самое интересное -- косвенные переходы типа 'jmp reg/jmp [mem]' . А в твоем случае, если я правильно понимаю, этого даже не нужно. Можно просто сравниваь по маске и выбирать при совпадении нужный адрес.
смотрю в книгу - вижу фигу... вместо адреса функции вижу какую-то ерунду и не могу понять об чем она! kd> db 0x8062B0C7 nt!PoShutdownBugCheck 8062b0c7 8b ff 55 8b ec 83 ec 14-80 7d 08 00 53 56 57 75 ..U......}..SVWu 8062b0d7 07 6a 00 e8 ea b5 fe ff-8b 45 18 8b 75 0c 8b 7d .j.......E..u..} 8062b0e7 10 8b 5d 14 6a 00 89 45-f8 8b 45 1c 68 04 00 00 ..].j..E..E.h... 8062b0f7 c0 89 45 fc 6a 04 8d 45-ec 6a 04 89 75 ec 89 7d ..E.j..E.j..u..} 8062b107 f0 89 5d f4 a3 38 41 55-80 e8 eb 1c eb ff ff 75 ..]..8AU.......u 8062b117 1c ff 75 18 53 57 56 e8-d0 86 f0 ff cc cc cc cc ..u.SWV......... 8062b127 cc cc 90 90 90 90 90 8b-ff 55 8b ec 8b 45 08 83 .........U...E.. 8062b137 f8 07 75 05 6a 02 58 eb-06 83 f8 02 7c 01 40 8b ..u.j.X.....|.@. соответствующий кусок кода в ИДА: PAGE:005540C7 _PoShutdownBugCheck@24: ; CODE XREF: ExUpdateSystemTimeFromCmos(x,x)+124Fp PAGE:005540C7 ; PAGELK:00594B9Cp PAGE:005540C7 mov edi, edi PAGE:005540C9 push ebp PAGE:005540CA mov ebp, esp PAGE:005540CC sub esp, 14h PAGE:005540CF cmp byte ptr [ebp+8], 0 PAGE:005540D3 push ebx PAGE:005540D4 push esi PAGE:005540D5 push edi PAGE:005540D6 jnz short loc_5540DF PAGE:005540D8 push 0 PAGE:005540DA call _IoConfigureCrashDump@4 ; IoConfigureCrashDump(x) но: kd> db nt!IoConfigureCrashDump 806166c9 8b ff 55 8b ec 53 56 57-64 a1 24 01 00 00 8b f8 ..U..SVWd.$..... 806166d9 8b 45 08 ff 8f d4 00 00-00 33 db 2b c3 74 41 48 .E.......3.+.tAH 806166e9 74 07 bb 10 00 00 c0 eb-54 e8 55 e9 00 00 8b d8 t.......T.U..... т.е. должно быть e8 806166c9, а там e8 fffeb5ea при этом hNTOSBase = 0x804D7000 чего я не понимаю?
- Не используй иду, возьми олю. Это гораздо удобнее. Ядро всеголишь модуль. - Вначале нужно знать что искать и знать где должны быть ссылки. Тоесть посмотреть сурцах. Для некоторого кода, как например хал нужно дизасмить чтобы понять. - После того как станет известно где ссылки, тоесть где искать переменную нужно сделать это для модулей всей линейки NT. Короче говоря нужно открыть модуль без символов и легко найти нужную переменную вручную.