1. Как получить указатель на PEB ?
peb = typedVar( "ntdll", "_PEB", getCurrentProcess() )
2. Какому модулю принадлежит адрес?
module = findModule( addr )
print module==None and "module not found" or module.name()
3. Как вывести текст с DML разметкой?
dprintln( "<u>Hello <b>World</b></u>", True )
4. Как передать в скрипт значение регистра?
Также, как и в любую команду windbg:
!py myscript @eax
Чтобы это работало, в скрипте нужно предусмотреть вычисление выражений:
param1 = expr( sys.argv[1] )
5. Как выполнить команду отладчика и получить ее результат?
print dbgCommand("!for_each_module")
Результат команды можно обработать к примеру с помощью RE.
6. Как получить размер структуры?
Проще всего так:
print hex( sizeof( "nt", "_ERESOURCE") )
Можно с через класс, предсталяющий информацию о типе (
typeClass):
print hex(getTypeClass("nt", "_ERESOURCE").sizeof())
Справедливо и для объектов дочернего класса
typedVarClass, например:
print hex(typedVar("nt", "_ERESOURCE", getOffset("nt", "CmpRegistryLock")).sizeof())
7. Как получить смещение поля структры?
Через класс, предсталяющий информацию о типе (
typeClass):
print hex(getTypeClass("nt", "_ETHREAD").Tcb.ThreadListEntry.offset())
Справедливо и для объектов дочернего класса
typedVarClass, например:
print hex(typedVar("nt", "_ETHREAD", getImplicitThread()).Tcb.ThreadListEntry.offset())
Но сравните результат выполнения двух команд:
print hex(getTypeClass("nt", "_ETHREAD").Tcb.ThreadListEntry.Flink.offset())
print hex(typedVar("nt", "_ETHREAD", getImplicitThread()).Tcb.ThreadListEntry.Flink.
offset())
Первая выводит ожидаемое значение, вторая - возвращает ошибку. Дело в том, что аттрибут 'Flink' в объекте
typedVarClass имеет встроенный тип python-а long и, соответственно, не имеет метода offset ( а также, getAddress() )
8. Есть ли в pykd команда help или другой способ получить справку?
В
pykd - нет. Но такая возможность встроена в сам python! Пробуем:
>!pycmd
>>> help()
help>pykd.typedVar
9. Как отлаживать скрипт?
Небольшие скрипты можно отладить прямо в windbg ( или в консоле ). Для этого используем встроенный отладчик pdb:
>!py pdb my_script.py
(pdb) s
-> import pykd
(pdb)
В более сложных случаях можно использовать любой отладчик python кода. Например, eсlipse или Visual Studio 2010 с плагином
pytools
10. Как сравнивать адреса?
Вопрос не так прост. DbgEng и все функции
pykd возращают адреса в 64 битном формате, даже для x86 платформы. Адреса, находящиеся в верхней половине адресного пространства, расширяются:
0x804f8925 -> 0xFFFFFFFF'804f8925
В следствии этого, в коде могут возникнуть непрогнозируемые ошибки. Рассмотрим пример:
if reg("eax")==getOffset( "nt", "NtCreateFile")
print "eax point to NtCreateFile"
На x86 платформе данный код будет работать неправильно. Переменная
a будет трактоваться как 32 битное целое, а функция getOffset вернет адрес, расширенный до 64 бит. И даже если регистр eax действительно указывает на NtCreateFile, проверка на равенство не сработает. Чтобы избежать этого, скастим значение регистра к указателю с помощью функции
addr64:
if addr64(reg("eax"))==getOffset("nt","NtCreateFile")
print "eax point to NtCReateFile"
Надеюсь, эта информация поможет начать работу с
pykd. На все вопросы мы с удовольствием ответим в этом блоге или по электронной почте:
pykd@hotmail.com.