
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[216.73.216.3] |
![]() |
|
Сообщ.
#1
,
|
|
|
Пытаюсь прочитать память процесса по заранее известному адресу.....
![]() ![]() HANDLE hQip=0; HANDLE hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0); PROCESSENTRY32 ProcEntry; ProcEntry.dwSize = sizeof(PROCESSENTRY32); Process32First(hSnapShot,&ProcEntry); do { if(lstrcmp("qip.exe",ProcEntry.szExeFile)==0) { hQip = OpenProcess(PROCESS_ALL_ACCESS,TRUE,ProcEntry.th32ProcessID); if(hQip==0) return 0; } } while(Process32Next(hSnapShot,&ProcEntry)); if(ReadProcessMemory(hQip,(PVOID)0x006A3AC,n,1000,&d) == 0) { d = GetLastError(); sprintf(n,"%d",d); MessageBox(HWND_DESKTOP,n,"pass:",0); } else { MessageBox(HWND_DESKTOP,n,"",0); } GetLastError() всегда говорит о 299 ошибке: Read\WriteProcessMemory запрос выполнен не полнустью. Чего это может быть ? |
Сообщ.
#2
,
|
|
|
barberan
во первых надо проверять ![]() ![]() if (hQip) { if(ReadProcessMemory(hQip,(PVOID)0x006A3AC,n,1000,&d) == 0) { d = GetLastError(); sprintf(n,"%d",d); MessageBox(HWND_DESKTOP,n,"pass:",0); } else { MessageBox(HWND_DESKTOP,n,"",0); } } во вторых адрес 0x006A3AC на разных платформах, системах, при разных условиях может быть разным. И в третьих, кто тебе сказал что там можно считать 1000 байт? Добавлено и в четверых посмотри чему равно d после вызова ReadProcessMemory. Добавлено и вообще код ОЧЕНЬ плохой, т.к. используешь одни и те же переменные для разных целей (n, d) |
Сообщ.
#3
,
|
|
|
Цитата Мальчиш @ во вторых адрес 0x006A3AC на разных платформах, системах, при разных условиях может быть разным. И в третьих, кто тебе сказал что там можно считать 1000 байт? Во-вторых - верно, а в-третьих - Майкрософт ![]() Т.к. память выделяется страницами не менее 4К, то либо адрес 0x06A3AC вообше не доступен, либо доступна вся страница до 0x06B000, т.е. 3156 байт А вот хватает ли размера переменной n для 1000 байт - из приведенного кода не видно |
Сообщ.
#4
,
|
|
|
if (hQip)
{ } это проверено заранее. адрес - заранее известен... из отладчика. а ошибка 299 - есть. |
Сообщ.
#5
,
|
|
|
Ошибка 299 вылезает и в том случае, когда память по адресу вообще не доступна. Проверь число прочитанных байт d - если 0, значит память по данному адресу вообще не выделена - можешь проверить по VirtualQueryEx
|
Сообщ.
#6
,
|
|
|
С этим разобрался, спасибо. А еще вопрос.. как в памяти процесса найти что-то определнное, и узнать по какому адресу оно лежит ?
|
Сообщ.
#7
,
|
|
|
Цитата barberan @ как в памяти процесса найти что-то определнное, и узнать по какому адресу оно лежит ? Сам понимаешь, вопрос не только не новый, но и достаточно "популярный" ![]() Краткий ответ: VirtualQueryEx + SetLength(s,pmi.RegionSize) + ReadProcessMemory(..,pointer(s),..) + Pos(..,s) Конкретные примеры найдешь поиском, например VirtualQueryEx и ReadProcessMemory |
Сообщ.
#8
,
|
|
|
Подскажите, как найти границы адресов процесса? Делаю так:
![]() ![]() MEMORY_BASIC_INFORMATION mbi; SIZE_T mbi_size = sizeof(mbi); DWORD startaddr=0, //начальный адрес lowaddr, //нижняя граница highaddr; //верхняя граница do { if( VirtualQueryEx(hQip,(LPCVOID)startaddr,&mbi,mbi_size) != sizeof(mbi)) { return 0; } startaddr+=(DWORD)mbi.RegionSize; }while(mbi.State != MEM_COMMIT); lowaddr = mbi.BaseAddress; //типа нашли нижнюю границу процесса. Через отладчик смарел... startaddr сначала +=65536 потом еще +=4096... Получается всего 2 страницы MEM_COMMIT чего быть то и не может. Сам вопрос вообще в том, что я не понимаю %) С какого адресса начинать VirtualQueryEx-ить... т.е. 2 арг. ф-ции - что туда передавать ? |
![]() |
Сообщ.
#9
,
|
|
Сообщ.
#10
,
|
|
|
Цитата barberan @ как найти границы адресов процесса? Получается всего 2 страницы MEM_COMMIT чего быть то и не может Еще как может ![]() Поэтому если ты точно знаешь, что твое искомое значение принадлежит секции данных образа или виндовой кучи, то можно определить соотв.диапазон адресов через ToolHelp АПИ и структуру PE-заголовка. Но определить диапазон адресов стека и тем более не виндовой кучи (например, борландовской) и уж тем более отдельно выделенных блоков - не так то просто. Поэтому проще просто просканировать всю память VirtualQueryEx с шагом 4 (или 64К), читая commited блоки и искать в них нужное значение |
Сообщ.
#11
,
|
|
|
Хм.. РАзобрался. А вот еще вопрос... ведь каждый адресс, если верить карте памяти состояит из 16 байт(или как это... - секций чтоли). В каждом байте(секции) хранится 1 символ. Иногда у меня странно считываетются не все 16(я точно не знаю что происходит), но знаючи, что например по данному адрессу "hello,world" я вижу чёта типа "lo,world" или "hello,wor". Что есть что?
![]() |
Сообщ.
#12
,
|
|
|
Цитата barberan @ ведь каждый адресс, если верить карте памяти состояит из 16 байт Не верь глазам своим ![]() ![]() |
Сообщ.
#13
,
|
|
|
а как бы это корректировать по ходу ??? ведь не знаю что увижу, толи леву половинку, толи правую. КАк быть?
|
Сообщ.
#14
,
|
|
|
Никак.
Не пойму, чего ты хочешь. Если нужно найти заданную строку, например, "hello,world" то и ищи ее в регионе памяти. Если же не знаешь, чего искать, и хочешь сам вывести карту памяти, то тебе по любому нужно будет как-то ограничивать длину выводимых строк, разбивая их по 8, 16 или 32 символа. При этом ес-но текст "hello,world" может оказаться в любом месте PS: В дельфи\BCB поиск подстроки реализуется легко - выделяем память под AnsiString через SetLength(s,mbi.RegionSize), читаем в строку весь регион и затем ищем подстроку функцией Pos. Такой поиск работает для любых бинарных данных, т.к. диапазон поиска ограничивается явно заданной длиной строки, а не нулевыми символами, которые могут встречаться в произвольных данных. Есть ли нечто подобное в C\C++ не знаю. Если нет, то придется организовать ручками: юзать в цикле strstr и перескакивать нулевые символы, пока не дойдем до конца региона |