Antonshka Опубликовано 27 ноября, 2020 Поделиться Опубликовано 27 ноября, 2020 Привет всем! У меня появилась необходимость записи и чтения файла через ассемблер СЕ. Через Lua CE это делается либо через writeRegionToFile readRegionFromFile либо через io.open Но я не могу использовать Lua потому что мне нужно производить запись или чтения файла именно в момент выполнения ассемблерной инструкции. На данный момент знаю лишь то что для осуществления записи и чтения файла через ассемблер СЕ нужно предварительно подготовить необходимые для этого аргументы и вызвать метод CreateFileA Спойлер HANDLE CreateFileA( LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile ); а затем WriteFile Спойлер BOOL WriteFile( HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite, LPDWORD lpNumberOfBytesWritten, LPOVERLAPPED lpOverlapped ); или ReadFile Спойлер BOOL ReadFile( HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped ); Но как это сделать через ассемблер СЕ я пока не понял. Именно, в какие регистры нужно записывать аргументы. Есть мысль что можно попробовать собрать СЕ трейнер или С++ приложение с функцией записи и чтения файла. Затем отладить их через например СЕ. Но это пока только мысль. Ссылка на комментарий Поделиться на другие сайты Поделиться
Xipho Опубликовано 27 ноября, 2020 Поделиться Опубликовано 27 ноября, 2020 2 часа назад, Antonshka сказал: Именно, в какие регистры нужно записывать аргументы. Это функции WinAPI, они написаны по соглашению stdcall, то есть, все параметры нужно запихнуть в стек (в обратном порядке, то есть справа налево), и затем сделать вызов нужной функции. Ссылка на комментарий Поделиться на другие сайты Поделиться
Antonshka Опубликовано 27 ноября, 2020 Автор Поделиться Опубликовано 27 ноября, 2020 9 часов назад, Xipho сказал: Это функции WinAPI, они написаны по соглашению stdcall, то есть, все параметры нужно запихнуть в стек (в обратном порядке, то есть справа налево), и затем сделать вызов нужной функции. Спасибо за направление. Прочитал про соглашения. Для 64 и 32 битных приложений способ передачи параметров оказался различный. Вот описание передачи параметров, если кому интересно. Спойлер https://docs.microsoft.com/ru-ru/cpp/build/x64-calling-convention?view=msvc-160 Протестировал на 32 и 64 битных приложениях. Файл создается, хендл закрывается, все хорошо. Завтра допишу методы на запись и чтение. В ходе экспериментов я наткнулся на одну интересную особенность. Объясните мне кто знает, почему так происходить. В 32 битном приложении, функция CreateFileA, после своего выполнения увеличивает ESP на количество переданных ей параметров умноженное на размер их типа (4 байта). То есть перед вызовом функции и после ее вызова ESP разный. Тоже с функцией CloseHandle, в 32 разрядном приложении, ESP после выполнения больше на 4 (функция принимает один параметр). То есть функции увеличивают ESP автоматически. В 64 битном приложении, RSP до и после вызова всегда одинаковый. Никакой автоматизации нет. Это такая особенность которую нужно просто принять как должное? Где можно прочитать о ней? Ссылка на комментарий Поделиться на другие сайты Поделиться
gmz Опубликовано 27 ноября, 2020 Поделиться Опубликовано 27 ноября, 2020 35 минут назад, Antonshka сказал: В 64 битном приложении, RSP до и после вызова всегда одинаковый. Никакой автоматизации нет. там статик стек, например: testz: struc .stack resq 4 .5 resq 1 alignb 16 resq 1 endstruc sub rsp,.stack_size mov ecx,1 mov edx,2 mov r8d,3 mov r9d,4 mov dword[rsp+.5],5 call [xxxxxxxx] mov ecx,1 call [xxxxx] add rsp,.stack_size ret где .5 макс количество параметров апи 1 1 Ссылка на комментарий Поделиться на другие сайты Поделиться
Xipho Опубликовано 27 ноября, 2020 Поделиться Опубликовано 27 ноября, 2020 2 часа назад, Antonshka сказал: Для 64 и 32 битных приложений способ передачи параметров оказался различный. Да, я забыл упомянуть про архитектуру Ссылка на комментарий Поделиться на другие сайты Поделиться
Antonshka Опубликовано 28 ноября, 2020 Автор Поделиться Опубликовано 28 ноября, 2020 (изменено) 14 часов назад, gmz сказал: там статик стек, например: Что делает твой пример кода? И что значит статик стек? Никак не пойму. Нашел вот в описании соглашений для 64 (по той ссылке что выложил выше) Спойлер The x64 ABI considers registers RBX, RBP, RDI, RSI, RSP, R12, R13, R14, R15, and XMM6-XMM15 nonvolatile. They must be saved and restored by a function that uses them. Поэтому регистр RSP неизменяется в 64 битном приложении до и после вызова функции? Потому что вызываемая функция должна восстановить его? Запись/чтение из файла, если кому-нибудь понадобится. Тест проводился на СЕ туториал 64 бит Запись Спойлер [ENABLE] alloc(PLACEASM_Write_File_scr_1,2048,"Tutorial-x86_64.exe"+2B08C) label(BACKASM_Write_File_scr_1) alloc(FileName,1000) registersymbol(FileName) alloc(FileData,1000) registersymbol(FileData) PLACEASM_Write_File_scr_1: pushfq push rax push rbx push rcx push rdx push rsi push rdi push r8 push r9 push r10 push r11 push r12 push r13 push r14 push r15 push rbp mov rbp,rsp sub rsp,40 and rsp,fffffffffffffff0 //-------------- Create File mov [rsp+30],0 mov [rsp+28],#128 mov [rsp+20],2 mov r9,0 mov r8,0 mov rdx,40000000 mov rcx,FileName call CreateFileA mov [rsp+38],rax // FileHandle //---------------- Write To File mov qword ptr [rsp+20],00000000 xor r9,r9 mov r8,#50 // Size mov rdx,FileData mov rcx,[rsp+38] // FileHandle call WriteFile //----------------- Close Handle mov rcx,[rsp+38] // FileHandle call CloseHandle //------------------------ add rsp,40 mov rsp,rbp pop rbp pop r15 pop r14 pop r13 pop r12 pop r11 pop r10 pop r9 pop r8 pop rdi pop rsi pop rdx pop rcx pop rbx pop rax popfq //------------------------ sub [rbx+000007F0],eax jmp BACKASM_Write_File_scr_1 /////////////////////////// FileName: db 'D:\Myf111002.txt',0 FileData: dd (float)1.554 /////////////////////////// "Tutorial-x86_64.exe"+2B08C: jmp PLACEASM_Write_File_scr_1 nop BACKASM_Write_File_scr_1: [DISABLE] dealloc(PLACEASM_Write_File_scr_1) "Tutorial-x86_64.exe"+2B08C: sub [rbx+000007F0],eax { // ORIGINAL CODE - INJECTION POINT: Tutorial-x86_64.exe+2B08C Tutorial-x86_64.exe+2B060: 55 - push rbp Tutorial-x86_64.exe+2B061: 48 89 E5 - mov rbp,rsp Tutorial-x86_64.exe+2B064: 48 8D A4 24 D0 FE FF FF - lea rsp,[rsp-00000130] Tutorial-x86_64.exe+2B06C: 48 89 9D F0 FE FF FF - mov [rbp-00000110],rbx Tutorial-x86_64.exe+2B073: 48 89 CB - mov rbx,rcx Tutorial-x86_64.exe+2B076: 48 C7 45 F8 00 00 00 00 - mov qword ptr [rbp-08],00000000 Tutorial-x86_64.exe+2B07E: 90 - nop Tutorial-x86_64.exe+2B07F: B9 05 00 00 00 - mov ecx,00000005 Tutorial-x86_64.exe+2B084: E8 D7 49 FE FF - call Tutorial-x86_64.exe+FA60 Tutorial-x86_64.exe+2B089: 83 C0 01 - add eax,01 // ---------- INJECTING HERE ---------- Tutorial-x86_64.exe+2B08C: 29 83 F0 07 00 00 - sub [rbx+000007F0],eax // ---------- DONE INJECTING ---------- Tutorial-x86_64.exe+2B092: 48 8D 4D F8 - lea rcx,[rbp-08] Tutorial-x86_64.exe+2B096: E8 85 DD FD FF - call Tutorial-x86_64.exe+8E20 Tutorial-x86_64.exe+2B09B: 8B 8B F0 07 00 00 - mov ecx,[rbx+000007F0] Tutorial-x86_64.exe+2B0A1: 41 B9 FF 00 00 00 - mov r9d,000000FF Tutorial-x86_64.exe+2B0A7: 4C 8D 85 F8 FE FF FF - lea r8,[rbp-00000108] Tutorial-x86_64.exe+2B0AE: 48 C7 C2 FF FF FF FF - mov rdx,FFFFFFFFFFFFFFFF Tutorial-x86_64.exe+2B0B5: 48 63 C9 - movsxd rcx,ecx Tutorial-x86_64.exe+2B0B8: E8 E3 AE FD FF - call Tutorial-x86_64.exe+5FA0 Tutorial-x86_64.exe+2B0BD: 45 31 C0 - xor r8d,r8d Tutorial-x86_64.exe+2B0C0: 48 8D 95 F8 FE FF FF - lea rdx,[rbp-00000108] } Чтение Спойлер [ENABLE] alloc(PLACEASM_Write_File_scr_1,2048,"Tutorial-x86_64.exe"+2B08C) label(BACKASM_Write_File_scr_1) alloc(FileSize,100) registersymbol(FileSize) PLACEASM_Write_File_scr_1: pushfq push rax push rbx push rcx push rdx push rsi push rdi push r8 push r9 push r10 push r11 push r12 push r13 push r14 push r15 push rbp mov rbp,rsp sub rsp,40 and rsp,fffffffffffffff0 //-------------- Create File mov [rsp+30],0 mov [rsp+28],#128 mov [rsp+20],3 mov r9,0 mov r8,0 mov rdx,80000000 mov rcx,FileName call CreateFileA mov [rsp+38],rax // FileHandle //---------------- Get File Size xor rdx,rdx mov rcx,[rsp+38] // FileHandle call GetFileSize mov [FileSize],rax //FileSize //---------------- Read From File mov qword ptr [rsp+20],00000000 xor r9,r9 mov r8,[FileSize] // FileSize mov rdx,FileData mov rcx,[rsp+38] // FileHandle call ReadFile //----------------- Close Handle mov rcx,[rsp+38] // FileHandle call CloseHandle //------------------------ add rsp,40 mov rsp,rbp pop rbp pop r15 pop r14 pop r13 pop r12 pop r11 pop r10 pop r9 pop r8 pop rdi pop rsi pop rdx pop rcx pop rbx pop rax popfq //------------------------ sub [rbx+000007F0],eax jmp BACKASM_Write_File_scr_1 /////////////////////////// FileName: db 'D:\Myf111002.txt',0 FileData: dd (float)1.554 /////////////////////////// "Tutorial-x86_64.exe"+2B08C: jmp PLACEASM_Write_File_scr_1 nop BACKASM_Write_File_scr_1: [DISABLE] dealloc(PLACEASM_Write_File_scr_1) "Tutorial-x86_64.exe"+2B08C: sub [rbx+000007F0],eax { // ORIGINAL CODE - INJECTION POINT: Tutorial-x86_64.exe+2B08C Tutorial-x86_64.exe+2B060: 55 - push rbp Tutorial-x86_64.exe+2B061: 48 89 E5 - mov rbp,rsp Tutorial-x86_64.exe+2B064: 48 8D A4 24 D0 FE FF FF - lea rsp,[rsp-00000130] Tutorial-x86_64.exe+2B06C: 48 89 9D F0 FE FF FF - mov [rbp-00000110],rbx Tutorial-x86_64.exe+2B073: 48 89 CB - mov rbx,rcx Tutorial-x86_64.exe+2B076: 48 C7 45 F8 00 00 00 00 - mov qword ptr [rbp-08],00000000 Tutorial-x86_64.exe+2B07E: 90 - nop Tutorial-x86_64.exe+2B07F: B9 05 00 00 00 - mov ecx,00000005 Tutorial-x86_64.exe+2B084: E8 D7 49 FE FF - call Tutorial-x86_64.exe+FA60 Tutorial-x86_64.exe+2B089: 83 C0 01 - add eax,01 // ---------- INJECTING HERE ---------- Tutorial-x86_64.exe+2B08C: 29 83 F0 07 00 00 - sub [rbx+000007F0],eax // ---------- DONE INJECTING ---------- Tutorial-x86_64.exe+2B092: 48 8D 4D F8 - lea rcx,[rbp-08] Tutorial-x86_64.exe+2B096: E8 85 DD FD FF - call Tutorial-x86_64.exe+8E20 Tutorial-x86_64.exe+2B09B: 8B 8B F0 07 00 00 - mov ecx,[rbx+000007F0] Tutorial-x86_64.exe+2B0A1: 41 B9 FF 00 00 00 - mov r9d,000000FF Tutorial-x86_64.exe+2B0A7: 4C 8D 85 F8 FE FF FF - lea r8,[rbp-00000108] Tutorial-x86_64.exe+2B0AE: 48 C7 C2 FF FF FF FF - mov rdx,FFFFFFFFFFFFFFFF Tutorial-x86_64.exe+2B0B5: 48 63 C9 - movsxd rcx,ecx Tutorial-x86_64.exe+2B0B8: E8 E3 AE FD FF - call Tutorial-x86_64.exe+5FA0 Tutorial-x86_64.exe+2B0BD: 45 31 C0 - xor r8d,r8d Tutorial-x86_64.exe+2B0C0: 48 8D 95 F8 FE FF FF - lea rdx,[rbp-00000108] } Изменено 28 ноября, 2020 пользователем Antonshka 1 Ссылка на комментарий Поделиться на другие сайты Поделиться
youneuoy Опубликовано 28 ноября, 2020 Поделиться Опубликовано 28 ноября, 2020 В 27.11.2020 в 08:13, Antonshka сказал: Но я не могу использовать Lua потому что мне нужно производить запись или чтения файла именно в момент выполнения ассемблерной инструкции. я такое делал при помощи функций дебаггера. Где-то на форуме видел тему про это и сделал по образцу. Выглядит как-то так: Спойлер changeregaddress=0x00a04f00 debug_removeBreakpoint(changeregaddress) function toFile(s) fl = io.open("c:\file.txt","a+") fl:write(s.."\n") fl:close() end function debugger_onBreakpoint() if (EIP == changeregaddress) then hasChangedARegister=true st=readString(readPointer(ESP+0x4),200) toFile(st) changedEAX=true debug_continueFromBreakpoint(0) return 1 else return 0 end end debug_setBreakpoint(changeregaddress) end debug_setBreakpoint(changeregaddress) Ссылка на комментарий Поделиться на другие сайты Поделиться
Antonshka Опубликовано 29 ноября, 2020 Автор Поделиться Опубликовано 29 ноября, 2020 20 часов назад, youneuoy сказал: я такое делал при помощи функций дебаггера. Где-то на форуме видел тему про это и сделал по образцу. Выглядит как-то так: Показать контент changeregaddress=0x00a04f00 debug_removeBreakpoint(changeregaddress) function toFile(s) fl = io.open("c:\file.txt","a+") fl:write(s.."\n") fl:close() end function debugger_onBreakpoint() if (EIP == changeregaddress) then hasChangedARegister=true st=readString(readPointer(ESP+0x4),200) toFile(st) changedEAX=true debug_continueFromBreakpoint(0) return 1 else return 0 end end debug_setBreakpoint(changeregaddress) end debug_setBreakpoint(changeregaddress) Спасибо! Но мне всё же WinAPI более пригляделся. Ссылка на комментарий Поделиться на другие сайты Поделиться
Рекомендуемые сообщения