· Начало · Отвђтить · Статистика · Поиск · FAQ · Правила · Установки · Язык · Выход · WASM.RU · Noir.Ru ·

 WASM Phorum —› WASM.RESEARCH —› бряки на содержимое памяти и чтение из места в файле

Посл.отвђт Сообщен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