|
|
| Посл.отвђт | Сообщенiе |
|
|
Дата: Янв 6, 2004 00:37:05 какими инструментами можно: 1. брякнуться на моменте чтения _определенного_ места из файла на диске (датабазы), т.е. например при чтении 256-го байта от начала файла ? 2. брякнуться по _определенному_ содержимому определенного места ОЗУ ? а не просто при записи или чтении туда чего попало... второе особливо важно при исследовании параметров, передаваемых через стек в какую-нить функцию, вызываемую достаточно часто с неинтересующими значениями парметров, а простой bpm на адреса стека в более менее сложной программе вообще похоже бесполезен бо в одни и те же адреса стека постоянно пишут разные места программы или ОС :/ ... т.е. я знаю в каком адресе ОЗУ будет находиться определенная величина при вызове функции, но ее же много раз вызывают и с другими значениями в этом же месте и как тогда программировать ЭВМ на останов по условию наличиа определенных байт не в регистре, а в ячейке общей памяти ? пока что для исследований в основном используется SoftIce 4.2.7 ... |
|
|
Дата: Янв 6, 2004 00:44:38 · Поправил: volodya bpm addr rw if (DWORD(**addr) == твое_значение) |
|
|
Дата: Янв 6, 2004 00:51:01 Drakon Rider По первому пункту тебе ничего не поможет ;-) По второму, используй условный бряк типа bpm адрес IF ... |
|
|
Дата: Янв 6, 2004 00:51:57 Ну вот пока писАл... ;-) |
|
|
Дата: Янв 6, 2004 01:01:49 А так всегда ;) |
|
|
Дата: Янв 7, 2004 16:48:16 >По первому пункту тебе ничего не поможет ;-) хмм... плохо это :/ ... пока что получается так: 1. ставлю бряк на CreateFileA с условием передачи через стек указателя на именя файла датабазы и после p ret получаю в EAX хендл файла... 2. ставлю бряк на ReadFile if (esp->4) == хендлу 3. пытаюсь делать s 0 l 7fffffff (известная последовательность байтов из файла обработку которой нужно отследить) и получаю pattern not found более десятков раз :/ ... бо игровая програма даже датабазу размером в 4 кб может читать по нескольку байт мноого раз :/ ... вопрос: можно ли в сайсе или др софте как-то поставить условный бряк на нахождение последовательности байт в указанном диапазоне областей памяти ? в Command Reference от сайса 4.3.0 в описании команды s идей про ее использование в условных бряках не видно :/ может какой плагин к сайсу есть ? или как делаются плагины к сайсу ? |
|
|
Дата: Янв 7, 2004 21:55:05 пробовал заняться отловом чтения из файла по изменению "указателя" на текущее место файла - если он примерно равен положению исследуемых байтов, то возможно они только что были прочитаны, особенно если чтение ведется более менее последовательно... вот что нарылось - оказывается у мелкософта нету функции GetFilePointer, зато есть воркароунд с юзанием SetFilePointer: если ее вызвать как invoke SetFilePointer hFile,0, NULL, FILE_CURRENT то в EAX (?) будет возвращен тот самый указатель на текущее место в файле... пытаюсь заюзать эту фичу: в пустое место секции команд программы вставляю:
и делаю бряки:
после бряка 02 выясняется хендл файла - 4C4 и соотв устанвливаю push 4С4 в доп программе... затем при бряке 00 когда система останавливается на адресе первой команды функции ReadFile вручную пытаюсь сделать переход на доп программу g =478400 после чего программа без ошибок сворачивается как и не было :/ ... откуда этот глюк ??? пробовал более сложный вариант - после возврата из ReadFile по команде p ret опять вызвать SetFilePointer типа push EAX ; сохраняется еах, который результат работы предыдущей ReadFile mov EAX,[ESP-14H] ; адрес возврата push EAX ; сохраняется в стеке push 1 ; FILE_CURRENT = 1 согласно windows.inc из масма push 0 ; NULL push 0 ; сдвиг на 0 push 4C4 ; hFile call SetFilePointer nop ; место под будущие условные бряки по содержимому EAX nop ; same here pop EAX pop EAX ; восст EAX jmp [ESP-8] ; возврат откуда пришло сюда... так вот в чем обломы: 1. без push 1 ; FILE_CURRENT = 1 согласно windows.inc из масма push 0 ; NULL push 0 ; сдвиг на 0 push 4C4 ; hFile call SetFilePointer сохранение и восстановление EAX и возврат из такой программы происходят нормально... но после забития стека парметрами для SetFilePointer и возврата из нее протятся данные для pop EAX pop EAX ; восст EAX jmp [ESP-8] ; возврат откуда пришло сюда... почему ??? вроде SetFilePointer должна сама за собой ESP отматывать куда положено и не портить данные от предыдущих push ... 2. SetFilePointer всегда возвращает 0хFFFFFFFF почему-то :/ ... согласно Вынь хелпу это одна из ошибок, хотя если хендл файла заведомо нормальный и непроизводится никакого "сдвига" то почему ошибка ? ЗЫЖ нашел IceExt с исходниками, но чем его собирать ? это же не под VC++ оказывается проект, но под какой-то C ... |
|
|
Дата: Янв 7, 2004 23:23:20 Drakon Rider C SetFilePointer информации о том где же находится указатель не получить. Так как позиция в файле 64-битная а эта функция возвращает только 32 бита. Попробуй использовать SetFilePointerEx. Она позволяет получить все 64 бита. Только при их интерпретации нужно быть осторожным, не исключено что они указывают за пределы файла. |
|
|
Дата: Янв 7, 2004 23:45:24 Black_mirror SetFilePointer возвращает младшие 32 бита указателя. Если файл маленький, то проблем быть не должно... |
|
|
Дата: Янв 8, 2004 00:23:32 · Поправил: Asterix Drakon Rider Ничего у тебя с SetFilePointer не получится, ты же не знаешь какими блоками читается файл, но правда можешь подсмотреть у ReadFile, но лучше исследовать работу самой ReadFile. Quantum Спасибо за посылку :-) |
|
|
Дата: Янв 10, 2004 17:03:58 хмм - оказывается IceExt надо собирать как раз прилагаемым к NT DDK компилятором и линкером ... причем вроде подошел софт от WinXP DDK... текущая частная задача была решена совместным юзанием бряка на SetFilePointer и поиском по памяти после возврата из ReadFile ... т.е. по подсмотренной установке указателя "достаточно близко" от нужного места где-то после 3..4 ReadFile и было найдено что нужно... но это как-то случайно и медленно... хотя можно модернизировать бряк на SetFilePointer задав бряк по диапазону значений указателя только ("вблизи или чуть меньше" чем искомое место в файле)... вопрос про IceExt - а где задается список команд, которые "добавляются" в сайс при загрузке iceext ? вроде просмотрел почти все исходники и поиском например dumpscreen находится только cmd_dumpscreen.cpp cmd_help.cpp iceext.def sources я пытаюсь добавить команду bpf (бряк по чтению/записи в опред место файла) и прописал ее в общий хелп - это работает... затем сделал cmd_bpf.cpp и туда вписал
DECLARE_API(bpf)
{
if (args[0] == '!') args += 6; // "! bpf "
if ( // check for help request
(args[0] == '/') &&
(
(args[1] == 'h') ||
(args[1] == 'H') ||
(args[1] == '?')
)
)
{
help_BPF();
return;
}
}
по аналогии с одной из имеющихся команд, еще добавил строку bpf в iceext.def и sources, все собирается без ошибок но при работе при наборе !bp в сайсе нету подсказки bpf и при попытке !bpf выдается extention command not found ... в инете линк на какой-то текст про добавление своих команд в сайс на reversing.net уже не работает - там только форум оставили :/ ... |
|
|
Дата: Янв 10, 2004 17:37:13 _http://mamaich.fuckru.net/fr_dox.htm |
|
|
Дата: Янв 10, 2004 22:29:07 · Поправил: Drakon Rider ок... я сделал тестовый файл на масме для проверки SetFilePointer - он вроде честно работает и возвращает положение указателя : invoke CreateFile, ADDR FileName, GENERIC_READ, FILE_SHARE_READ,\ ADDR SecurAttrib, OPEN_EXISTING,\ FILE_ATTRIBUTE_NORMAL or FILE_FLAG_SEQUENTIAL_SCAN, NULL mov hFile,EAX test EAX,EAX jz mFileError invoke SetFilePointer, hFile, 0, 0, FILE_CURRENT ; ТУТ ВОЗВРАЩАЕТ 0 invoke GlobalAlloc,GMEM_MOVEABLE or GMEM_ZEROINIT,MEMSIZE mov hMemory,eax invoke GlobalLock,hMemory mov pMemory,eax invoke ReadFile, hFile, pMemory,10,ADDR SizeReadWrite,NULL invoke SetFilePointer, hFile, 0, 0, FILE_CURRENT ; ТУТ ВОЗВРАЩАЕТ 0AH и если сделать бряк на ReadFile и перенаправить выполнение на invoke SetFilePointer, hFile, 0, 0, FILE_CURRENT jmp ReadFile то опять и позиция указателя правильно возвращается и со стеком все в порядке... и далее ReadFile выполняется без ошибок и все завершается нормально... но при разборе работы бряка из ReadFile вызванного из игровой программы : push 1 ; FILE_CURRENT = 1 согласно windows.inc из масма push 0 ; NULL push 0 ; сдвиг на 0 push 4C4 ; hFile call SetFilePointer после возврата в EAX все время 0FFFFFFFFH и ESP _нескорркетирован_ на 2 единицы (это даже некратно 4) ! т.е. если продолжить выполнение ReadFile после этого, то возникает исключение в kernel32 и похоже при этом как раз игровая программа схлопывается без следов... даже faults on в сайсе не замечает этого... но если сделать sub esp,2 перед переходом обратно на ReadFile, то в принципе ReadFile работает сколько надо раз и остальное из исследуемой игровой программы тоже... при попытке трассирования такой "ошибочной" SetFilePointer виден вызов SetLastError и нету вызовов NtQueryInformationFile (которая похоже и возвращает положение указателя в "нормальном режиме", но даже в Win DDK она не описана :/ ) ... я попробовал поставить GetLastError после вызова SetFilePointer - оно возвращает код ошибки 57Н, но как это расшифровать ? попытки в масме invoke FormatMessage,\ FORMAT_MESSAGE_ALLOCATE_BUFFER or FORMAT_MESSAGE_FROM_SYSTEM,\ NULL, 57H, 2048, ADDR MsgBuf, 0, NULL invoke MessageBox, NULL, ADDR MsgBuf, addr MsgCaption, MB_OK приводят к формированию строки в буфере MsgBuf ок 3 байт :/ ... |
|
|
Дата: Янв 11, 2004 12:02:01 · Поправил: Drakon Rider кое-что получилось с iceext сделать - оказывается есть такая ядреная функция ZwQueryInformaionFile которая тоже может вернуть в одном из вариантов указатель... в результате было добавлено:
extern "C" {
#include <ntddk.h>
}
#include <windef.h>
#include <ntverp.h>
#include <stdio.h>
#include <string.h>
#include "wdbgexts.h"
#include "defs.h"
#include "softice.h"
#include "screen.h"
extern void help_FPOS(void);
DWORD KDFilePos = 0;
////////////////////////////////////////////////////////////////////// //////
//
// FPOS
//
// Function, returns 32bit file pointer.
//
////////////////////////////////////////////////////////////////////// //////
DECLARE_API(fpos)
{
HANDLE hFile=0;
IO_STATUS_BLOCK iosb;
DWORD fpibuf[2];
if (args[0] == '!') args += 7; // "! fpos "
if ( // check for help request
(args[0] == '/') &&
(
(args[1] == 'h') ||
(args[1] == 'H') ||
(args[1] == '?')
)
)
{
help_FPOS();
return;
}
if (args[0] == 0)
{
help_FPOS();
return;
}
{
__asm // si_Expression2Integer is very asm-specific function
{
mov esi, args
push esi
call si_Expression2Integer
jb syntax_error
mov hFile, eax
}
DbgPrint ("hFile %08X\n", hFile);
ZwQueryInformationFile( hFile, &iosb, &fpibuf,\
sizeof( fpibuf ), FilePositionInformation );
// fpibuf[1] high order or 64bit position - possibly never used
// fpibuf[0] low order of 64bit position for files from 0 to 2 Gb
DbgPrint ("FilePos %08X\n", fpibuf[0]);
KDFilePos = fpibuf[0];
return ;
}
{
syntax_error:
help_FPOS();
}
}
которое реализовало команду !fpos с параметром hFile ... теперь при бряке на системное ReadFile типа bpx ReadFile DO "!fpos Esp->4" при чтении файла "по F3" из FAR получается:
т.е. вроде похоже на работу, но теперь бы вернуть этот DWORD как результат работы !fpos чтобы применить в следующем сайсовом условном бряке, но при попытке return PosLow; компилер матерится, что void return value :( ... т.е. DECLARE_API это таки void ??? а как в сайс вернуть значение ? |
|
|
Дата: Янв 11, 2004 15:47:58 · Поправил: Drakon Rider усе - теперь самое запарное автоматизировано полностью - возврат значения указателя сделал через запись в ячейку памяти, укзатель на которую (KDFilePos) виден из сайса бо в winice.dat прописано EXP=path\IceExt.sys (как иначе импортить в сайс символы из загружаемого KDE ?) теперь работает так: сначала bpx CreateFileA и выяснить хендл файла затем bpx ReadFile if ((esp->4) == hFile) DO "!fpos hFile;x" затем бряк на следующую инструкцию после ReadFile bpx ReadFile+1 if (*KDFilePos+(esp->10) > myLookingFilePos) && ((esp->8) == hFile) && (*KDFilePos < myLookingFilePos) где esp->10 - сколько будет считываться в данной ReadFile после этого бряка можно посмотреть куда будет считываться и там уже после p ret найти с помощью s или дальше посчитать точный адрес и даже bpm поставить... все это дело на iCeleron1000->1300 работает где-то со скоростью ок 2..3 бряка в секунду и нужный бряк определяется где-то через 200 вызовов ReadFile - меньше двух минут работы ПЭВМ в автоматическом режиме по программе :) так что времени вообщем сэкономлено немало... исходники мода для iceext : [url=ftp://au:au@files.drakan.ru/pub/dev_tools/iceext/iceext057Fposmod 01src.zip ]ftp://au:au@files.drakan.ru/pub/dev_tools/iceext/iceext057Fposmod01sr c .zip [/url] собранный мод: ftp://au:au@files.drakan.ru/pub/dev_tools/iceext/iceext057Fposmod01.zi p |
|
Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.184 |