Здравствуйте! Почему не работает следующий код: Код (Text): ;hWnd - хэндл диалогового окна GetHWND proc hWnd:HWND LOCAL PID:DWORD LOCAL hBuf:HWND invoke FindWindow,addr CLASS_NAME,addr WINDOW_NAME .if eax==NULL invoke MessageBox,hWnd,addr errtext,addr mescaption,MB_OK or MB_ICONERROR or MB_APPLMODAL mov eax, -12 ret .endif mov hBuf, eax invoke GetWindowThreadProcessId,hBuf,addr PID invoke OpenProcess,PROCESS_ALL_ACCESS,FALSE,PID .if eax==NULL invoke MessageBox,hWnd,addr errtext,addr mescaption,MB_OK or MB_ICONERROR or MB_APPLMODAL mov eax, -12 .endif ret GetHWND endp ;address - указатель на адрес для чтения/записи ;val - указатель на значение для записи ;isRead - определяет, вызывается ли функция для чтения или нет ;siz - размер данных для чтения/записи ;mHWND - хэндл диалогового окна TrnEng PROC address:LPVOID,val:LPVOID,isRead:BOOL,siz:DWORD,mHWND:HWND LOCAL oldaccess:DWORD LOCAL pHWND:HWND invoke GetHWND,mHWND mov pHWND, eax .if pHWND==-12 invoke MessageBox,addr mHWND,addr uerrtxt,addr mescaption,MB_OK or MB_ICONERROR or MB_APPLMODAL mov eax, -12 ret .endif invoke VirtualProtectEx,pHWND,address,siz,PAGE_EXECUTE_READWRITE,addr oldaccess .if isRead==TRUE invoke ReadProcessMemory,pHWND,address,eax,siz,NULL .else invoke WriteProcessMemory,pHWND,address,val,siz,NULL .endif push eax invoke VirtualProtectEx,pHWND,address,siz,oldaccess,oldaccess invoke CloseHandle,pHWND pop eax ret TrnEng endp OllyDbg пишет, что при выполнении инструкции ReadProcessMemory возникает ошибка ERROR_NOACCESS. Причём все хэндлы, PID`ы и всё остальное возвращаются правильно.
BOOL ReadProcessMemory( HANDLE hProcess, // handle of the process whose memory is read LPCVOID lpBaseAddress, // address to start reading LPVOID lpBuffer, // address of buffer to place read data DWORD nSize, // number of bytes to read LPDWORD lpNumberOfBytesRead // address of number of bytes read );
Ес-но, ты куда пытаешься данные считать - по несуществующему адресу lpBuffer = eax, который после BOOL VirtualProtect() = TRUE или FALSE
ошибки больше нет, но значение всё равно 0. Может быть, это из-за того, что по адресу находится значение типа FLOAT? Для преобразования его (значения) в строку я использую msvcrt.sprintf. Вот код функции, может там что-то не так? Код (Text): ;isMoney - значение, показывающее, является ли значение типа FLOAT внутриигровыми деньгами (TRUE) или рейтингом (FALSE) ;value - значение типа DWORD (в игре деньги вряд ли будут больше даже 10 млн.), конвертируется в QWORD ;переменная Money - QWORD (Money dq ?); szMsvcrt - BYTE (szMsvcrt db 'msvcrt.dll',0) ;szSprintf - BYTE (szSprintf db 'sprintf',0); szFloat - BYTE (szFloat db '%f',0) ;moneybuf - BYTE (moneybuf db ?) RealToStr proc isMoney:BOOL,value:DWORD invoke LoadLibrary,offset szMsvcrt invoke GetProcAddress,eax,offset szSprintf .if isMoney==TRUE mov edx, value mov dword ptr money, edx mov dword ptr money+4, 0 push dword ptr money+4 push dword ptr money push offset szFloat push offset moneybuf call eax .else .endif add esp, 3*4 ret 8 RealToStr endp и если уж на то пошло, как отбросить дробную часть числа типа FLOAT?
q_q понятно, вот они: address = 00679020h pHWND = 5C (но разве эта величина должна быть постоянной?) вместо eax теперь у меня стоит addr valBuf (LOCAL valBufWORD) siz = 4 NULL = 0
DPX по адресу находится значение типа FLOAT Покажи восемь байт по адресу. В masm32.lib есть fptoa.asm и fptoa2.asm, в fpu.lib есть FpuFLtoA.asm.
60 30 DE 48 04 00 00 00 кстати, как использовать эти функции? В смысле, какой параметр за что отвечает? А то в MSDN этого, вроде, нету.
оказывается, всё дело в неправильной функции RealToStr! С помощью FloatToStr в masm32.lib всё получилось, но минус в том, что значение функция возвращает в виде мантиссы и экспоненты, а мне надо десятичное число! Как с этим справиться?
DPX > "минус в том, что значение функция возвращает в виде мантиссы и экспоненты, а мне надо десятичное число!" Во-первых, FloatToStr представлет в децимальном виде только числа от 0.1 <= x < 10^7, а для увеличения диапазона до x < |10^16| нужно использовать FloatToStr2 (см.комменты в fptoa.asm и fptoa2.asm). Во-вторых, как ты в децимальном виде хочешь представить число (?) 6030DE4804000000 ~ 2.26E+155 если старшие разряды слева или ~ 9.09E-314 если старшие справа (denormal). Или может это 32-бит single 0x48DE3060h = 455043 ? Или ты не по тому адресу свои money читаешь ?
в общем я со всем разобрался, но остался единственный вопрос: как преобразовать 80-bit LONG DOUBLE (или 64-bit DOUBLE) в 32-bit FLOAT, или как преобразовать строку в 32-bit FLOAT?
Все преобразования вещ.чисел делаются путем загрузки в FPU в одном формате и выгрузке в другом. Загрузка: fld tbyte [..] ;загрузить extended 80-бит fld qword [..] ;загрузить double 64-бит fld dword [..] ;загрузить single 32-бит fild dword [..] ;загрузить целое 32-бит Выгрузка: делается аналогично командой fstp для сохранения в вещ.формате или fistp - для преобразования к целому dword или qword. Если твои money целые, то проще и работать с 32-битными числами: fild dword [imoney] ;грузим целое fstp dword [fmoney] ;сохраняем как вещественное