Помогите реализовать максимально быстрый поиск заданной строки в памяти процесса. Набросал код поблочного чтения, могет можно как-то оптимизировать по скорости этот код, или предложите свой вариант... Код (Text): .686p .mmx .model flat,stdcall option casemap:none include \masm32\include\ntdll.inc includelib \masm32\lib\ntdll.lib include \masm32\include\kernel32.inc includelib \masm32\lib\kernel32.lib include \masm32\include\user32.inc includelib \masm32\lib\user32.lib .data szString db "строка которую нужно изменить",0 szNewString db "новая строка с той же длиной",0 .code FindWriteMemory proc uses esi edi ebx ProcessHandle:dword,lpString:dword,lpNewString:dword,lpStringsLen:dword local ReturnLength:dword local SystemInformation:SYSTEM_BASIC_INFORMATION local AllocationBase:dword local AllocationSize:dword local MemoryInformation:MEMORY_BASIC_INFORMATION local RegionLenght:dword invoke ZwQuerySystemInformation,SystemBasicInformation,addr SystemInformation,sizeof SYSTEM_BASIC_INFORMATION,addr ReturnLength .if eax == 0 mov AllocationSize,1024*2024 mov AllocationBase,0 invoke ZwAllocateVirtualMemory,-1,addr AllocationBase,0,addr AllocationSize,MEM_COMMIT,PAGE_READWRITE .if eax == 0 mov edi,AllocationBase NextRegionMemory: invoke ZwQueryVirtualMemory,ProcessHandle,SystemInformation.LowestUserAddress,MemoryBasicInformation,addr MemoryInformation,sizeof MEMORY_BASIC_INFORMATION,addr ReturnLength .if eax == 0 cmp MemoryInformation.State,MEM_COMMIT or MEM_RESERVE jz NextRegionMemory NextFragmentMemory: .if MemoryInformation.RegionSize <= 1024*2024 mov eax,MemoryInformation.RegionSize .else mov eax,1024*2024 .endif mov RegionLenght,eax invoke ZwReadVirtualMemory,ProcessHandle,MemoryInformation.BaseAddress,edi,RegionLenght,0 .if eax == 0 mov esi,RegionLenght mov ebx,esi @@: invoke memcmp,edi,lpString,lpStringsLen .if eax == 0 mov eax,MemoryInformation.BaseAddress sub eax,RegionLenght add eax,ebx ;определяем адрес invoke ZwWriteVirtualMemory,ProcessHandle,eax,lpNewString,lpStringsLen,0 .endif inc edi inc ebx dec esi jnz @B .endif .if MemoryInformation.RegionSize <= 1024*2024 mov eax,MemoryInformation.BaseAddress add eax,MemoryInformation.RegionSize mov SystemInformation.LowestUserAddress,eax cmp eax,SystemInformation.HighestUserAddress jc NextRegionMemory .else mov eax,1024*2024 sub MemoryInformation.RegionSize,eax add MemoryInformation.BaseAddress,eax jmp NextFragmentMemory .endif .endif invoke ZwFreeVirtualMemory,-1,addr AllocationBase,addr AllocationSize,MEM_RELEASE .endif .endif ret FindWriteMemory endp start proc local Buffer[1024]:byte invoke lstrcpy,addr Buffer,offset szString invoke FindWriteMemory,-1,offset szString,offset szNewString,sizeof szString invoke MessageBox,0,offset szString,addr Buffer,0 invoke ExitProcess,0 start endp end start
Нужен алгоритм поиска побыстрее. Используй алгоритм Кнута-Морриса-Пратта. Только не влоб. Нужно организовать поблочное чтение памяти, а внутри блока искать КМП. Когда блок заканчивается, подгрузить новый и продолжить поиск.
Сомневаюсь, что она возможна, эта лучшая схема. Единственный возможный способ искать быстрее, это использовать более быстрый алгоритм поиска. И здесь уже ты можешь извращаться как хочешь. Например memcmp требует очень много времени за счет того, что ты по много раз будешь проверять один и тот же байт. Алгоритм КМП будет проверять каждый байт только один раз. Лучше быть уже не может. Улучшения могут быть лишь в упрощении реализации. Ты можешь выбрать любой из быстрых алгоритмов поиска подстроки. Если хочешь чего-нибудь попроще, то используй хеширование (Если использовать нужный хеш, то ты можешь пересчитывать за константу, при сдвиге на один байт вперед) Сверяешь хеш куска памяти нужного размера, с хешем того, что ты ищешь. Если совпадают, то проверяй memcmp, если нет - то идешь дальше. При хорошем подборе алгоритма хеширования, ты будешь вызывать memcmp крайне редко.