У меня возникла проблема. Долго создаю программу (С++), смысл которой - поменять в процессе все определенные строки на другие. Долго маялся, пока не соорудил почти рабочий код. Он заменяет все повторы только первой строки, после чего вываливается (при первом запуске renamestr). Реализация такая - процесс запускается, дается 10 сек на загрузку, затем подгружается длл, происходят полный поиск и замена. В итоге проходит 10 сек, процесс подвисает (кстати, оптимизирую поиск потом). Как я выяснил по логам (из кода я их вырезал), после замены всех строк функция memstr выходит за границы допустимой памяти и останавливается - возможно, неправильно определяется размер памяти процесса. Кстати, есть особенность - строки должны заменяться только при условии, что они окружены нулевыми символами. Код (Text): #include "stdafx.h" #include <stdio.h> #include <string.h> #include <io.h> #include <psapi.h> #pragma comment(linker, "/DEFAULTLIB:psapi.lib") char * memstr (const char *big, const char *little, size_t len) { size_t littlelen = strlen (little); char *p = (char*) big; size_t i; if (*little == '\0') return 0; if (len < littlelen) return NULL; for (i = 1; i <= len - littlelen - 1; i++){ if (memcmp (&p[i], little, littlelen) == 0 && p[i+littlelen] == 0 && p[i-1] == 0 ){ return &p[i]; } } return NULL; } #ifdef _MANAGED #pragma managed(push, off) #endif size_t GetAppMemUsage(){ PROCESS_MEMORY_COUNTERS pmc; pmc.cb = sizeof(pmc); GetProcessMemoryInfo(GetCurrentProcess(), &pmc, sizeof(pmc)); return pmc.WorkingSetSize; } int renamestr(char * oldstr, char * newstr){ DWORD written; char * res; char chbuf[32]; size_t len=strlen(oldstr),len2=strlen(newstr); if(len2>len) return -1; size_t size=GetAppMemUsage(); bool check=0; long adr=0x1400000; do{ strcpy(chbuf,newstr); chbuf[strlen(chbuf)]='\0'; res=memstr((char*)adr,oldstr,size - adr); if(res){ adr=(DWORD)res+1; check=1; WriteProcessMemory(GetCurrentProcess(),res,chbuf,len2+1,&written); } } while (res); if (check) return 1; return 0; }
Конечно не правильно, т.к. тут нужно определять размер выделенного непрерывного региона виртуальной памяти через VirtualQuery (ну или адреса и размеры секций образа из PE-заголовка). А WorkingSetSize тут вообще ни к месту, т.к. он показывает суммарный объем физ.памяти, занимаемый процессом в данный момент, и соотв-но, во-первых, включает в себя выделенные страницы из разных\разрозненных регионов вирт.памяти - стека, кучи, твоей длл и прочей "всякой всячины", а во-вторых, может включать в себя не весь размер образа экзешника, а только часть страниц, загруженную в память данный момент (см. Working Set)
Спасибо, как раз давеча книгу Рихтера скачал. Только, блин, не компилится его VMMap, выдает кучу ошибок на ровном месте
Booster Спасибо, я и не знал. Книжки читать надо, оказывается, кто бы мог подумать? Только можно догадаться, что я экспериментирую. Или хочу использовать программу по назначению.
Zlyden Запомни, каков вопрос таков и ответ. Ваше "на ровном месте" нам ничего не говорит. Экспериментируй на здоровье.
Booster Я не спрашивал, почему не компилится, я просто заметил. С этими вещами я вполне способен разобраться сам - более того, уже разобрался, кто-то накосячил в CmnHdr.h