Всем доброго времени суток Есть код который выделяет на стеке структуры для STARTUPINFOA+PROCESS_INFORMATION - и запускает cmd используя CreateProcessA. Все работает кроме одного: когда я передаю имя cmd.exe не через заранее объявленную переменную, а также выделяя память на стеке - ошибка в дебагере 0000007B (ERROR_INVALID_NAME) . наверное, что то очень простое должно быть - может кто-то подсказать что не правильно делаю? Код (ASM): ;ml64.exe CreateProcessA_memory_from_stack.asm /link /subsystem:console /entry:main /LIBPATH:"C:\Program Files (x86)\Windows Kits\10\Lib\10.0.18362.0\um\x64" /defaultlib:kernel32.lib extrn CreateProcessA : proc extrn ExitProcess : proc .const NORMAL_PRIORITY_CLASS equ 020h .data szProcName db "cmd.exe" .code main proc sub RSP, 28h ; 40 bytes of shadow space and RSP, 0FFFFFFFFFFFFFFF0h ;Align the stack to a multiple of 16 bytes ;------------------------------- чистим пам¤ть сразу под STARTUPINFOA+PROCESS_INFORMATION lea rsi,qword ptr [rsp-200h] ; mov rcx,rsi mov rdx,rsi add rdx, 80h Z: MOV BYTE PTR [RSI],00h INC rsi CMP rsi,rdx JLE Z mov rsi,rcx mov dword ptr [rsi],68h ; начало STARTUPINFOA add rcx, 68h ; начало PROCESS_INFORMATION push rcx push rsi push 00h push 00h push NORMAL_PRIORITY_CLASS push 00h sub rsp, 20h mov r9, 00h mov r8, 00h mov rdx, 00h ;------------------------------НЕ РАБОЧИЙ ВАРИАНТ КОДА lea rax,qword ptr [rsp-100h] mov rcx, 6578652E646D63h ; cmd.exe mov qword ptr [rax],rcx ; lea rcx,qword ptr [rsp-100h] ;------------------------------ ;------------------------------ А ВОТ ЧЕРЕЗ ПЕРЕМЕННУЮ szProcName ВСЕ РАБОТАЕТ ;lea rcx, szProcName call CreateProcessA xor rcx, rcx call ExitProcess main endp end
rsp-100h это что? Память над указателем стека? Я не вижу чтоб вы поднимали стек. --- Сообщение объединено, 4 фев 2022 --- Ух ты ж блин, а я и не в курсе что такое есть. Каким туториалом пользуетесь?
Я было испугался, что отныне можно использовать адреса младше верхушки стека, ан нет. Твою строчку с адресом младше rsp вендовые функции закономерно сжирают под свои нужды, а когда дело доходит до ее использования, оказывается, что там шляпа. Не выёживайся и выделяй локальные переменные, если в этом во всём плывешь.
Ой да ладно, новичку вполне может быть непонятно что API вызовы тоже используют стек, это нифига неочевидно. Он может еще сам бы догадался, если бы получил краш, но ему "повезло". Он наверное это и хотел, но не понял как. --- Сообщение объединено, 4 фев 2022 --- f13nd, где почитать про shadow space и подобные приколы? Я похоже тоже в этом плыву )
https://docs.microsoft.com/en-us/cpp/build/x64-calling-convention?view=msvc-170 Похоже этим очередным пафосным термином обозначают 4 кворда, где по идее должны быть 4 первых аргумента, но не бывают. Потому что находятся в rcx,rdx,r8 и r9.
Зачем этот дроч, если masm это МАКРОассемблер? Юзайте invoke! http://dsmhelp.narod.ru/environment.htm#id_newinvoke или вот нашел у себя, сам когда то юзал, вродебы: Спойлер Код (Text): uinvoke macro p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12, \ p13,p14,p15,p16,p17,p18,p19,p20,p21,p22 count = 4 FOR arg,<p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,\ p15,p16,p17,p18,p19,p20,p21,p22> IFNB <arg> mov qword ptr[rsp+count*8],arg count = count + 1 ENDIF ENDM IFNB <p1> IF (OPATTR (p1)) AND 00010000y ;; Is a register value IFDIFI <p1>, <rcx> ;; do not move ecx onto itself mov rcx, p1 ENDIF ELSEIF (OPATTR (p1)) AND 00000100y ;; Is an immediate value IF p1 EQ 0 xor rcx, rcx ELSEIF p1 EQ 1 xor rcx, rcx inc rcx ELSEIF p1 EQ -1 or rcx, -1 ELSE mov rcx, p1 ENDIF ELSE mov ecx, r1 ENDIF IFNB <p2> IF (OPATTR (p2)) AND 00010000y ;; Is a register value IFDIFI <p2>, <rdx> ;; do not move edx onto itself mov rdx, p2 ENDIF ELSEIF (OPATTR (p2)) AND 00000100y ;; Is an immediate value IF p2 EQ 0 xor rdx, rdx ELSEIF p2 EQ 1 xor rdx, rdx inc rdx ELSEIF p2 EQ -1 or rdx, -1 ELSE mov rdx, p2 ENDIF ELSE mov rdx, p2 ENDIF IFNB <p3> IF (OPATTR (p3)) AND 00010000y ;; Is a register value IFDIFI <p3>, <r8> ;; do not move edx onto itself mov r8, p3 ENDIF ELSEIF (OPATTR (p3)) AND 00000100y ;; Is an immediate value IF p3 EQ 0 xor r8, r8 ELSEIF p3 EQ 1 xor r8, r8 inc r8 ELSEIF p3 EQ -1 or r8, -1 ELSE mov r8, p3 ENDIF ELSE mov r8, p3 ENDIF IFNB <p4> IF (OPATTR (p4)) AND 00010000y ;; Is a register value IFDIFI <p4>, <r9> ;; do not move edx onto itself mov r9, p4 ENDIF ELSEIF (OPATTR (p4)) AND 00000100y ;; Is an immediate value IF p4 EQ 0 xor r9, r9 ELSEIF p4 EQ 1 xor r9, r9 inc r9 ELSEIF p4 EQ -1 or r9, -1 ELSE mov r9, p4 ENDIF ELSE mov r9, p4 ENDIF ENDIF ENDIF ENDIF ENDIF call p0 endm
Дроч-то не в вызове, а в организации пространства под 3 переменных. В цикле чистки нулями я вижу мимикрию под модные цэ-компилеры, оно как бы с одной стороны хорошо, с другой - прекрасно налезет и на пачку локальных переменных. Да к тому же экономия пары байт не стоит того, чтобы так упарываться. Никого эта пара байт счастливыми не сделает.
да какие там аверы, если чел в отладчике не может посмотреть почему не работает? с макросами хотя бы код нагляден
Так можно это на nasm сделать: Код (Text): global main default rel extern RtlZeroMemory extern CreateProcessW extern ExitProcess struc STARTUPINFO .cb resd 1 alignb 8 .lpReserved resq 1 .lpDesktop resq 1 .lpTitle resq 1 .dwX resd 1 .dwY resd 1 .dwXSize resd 1 .dwYSize resd 1 .dwXCountChars resd 1 .dwYCountChars resd 1 .dwFillAttribute resd 1 .dwFlags resd 1 .wShowWindow resw 1 .cbReserved2 resw 1 alignb 8 .lpReserved2 resq 1 .hStdInput resq 1 .hStdOutput resq 1 .hStdError resq 1 endstruc struc PROCESS_INFORMATION .hProcess resq 1 .hThread resq 1 .dwProcessId resd 1 .dwThreadId resd 1 endstruc section .code main: struc .stack resq 4 .5 resq 1 .6 resq 1 .7 resq 1 .8 resq 1 .9 resq 1 .10 resq 1 .StartupInfo resb STARTUPINFO_size .ProcessInfo resb PROCESS_INFORMATION_size alignb 16 resq 1 endstruc sub rsp,.stack_size lea rcx,[rsp+.StartupInfo] mov edx,STARTUPINFO_size call RtlZeroMemory xor rcx,rcx lea rdx,[CommandLine] mov r8,rcx mov r9,rcx mov [rsp+.5],rcx mov dword[rsp+.6],0x20 ;NORMAL_PRIORITY_CLASS mov [rsp+.7],rcx mov [rsp+.8],rcx lea rax,[rsp+.StartupInfo] mov [rsp+.9],rax lea rax,[rsp+.ProcessInfo] mov [rsp+.10],rax call CreateProcessW mov rcx,rax call ExitProcess add rsp,.stack_size ret section .data align 4,db 0 CommandLine dw __utf16__ 'cmd.exe',0 сборка: Код (Text): nasm -f win64 main.asm gcc main.obj
Ладно хоть не tasm Код (ASM): format PE64 GUI 5.0 entry main include 'win64ax.inc' section '.text' code readable executable proc main locals binStartupInfo STARTUPINFO binProcessInfo PROCESS_INFORMATION szCmd rb MAX_PATH endl and rsp,not(32-1) mov rax,rsp neg rax invoke memset,addr binStartupInfo,0,addr rax+rbp mov DWORD[szCmd + 00],'cmd.' mov DWORD[szCmd + 04],'exe' mov [binStartupInfo.cb],sizeof.STARTUPINFO invoke CreateProcessA,0,addr szCmd,0,0,0,NORMAL_PRIORITY_CLASS,0,0,addr binStartupInfo,addr binProcessInfo invoke ExitProcess,0 ret endp section '.idata' import data readable library kernel32,'KERNEL32.DLL',user32,'USER32.DLL',ntdll,'ntdll.dll' include 'api\kernel32.inc' include 'api\user32.inc' import ntdll,\ memset,'memset'
Archimag, > ERROR_INVALID_NAME Дебилы, вас пора автоматикой банить за такие вопросы. Статус смотри дебил.
Недавно был вопрос по статусным кодам. Ели человек самостоятельно не может инфу найти, но он же тут пост создал значит печатать может. О чём это может говорить, тем более есть сурки на всё это.
Если бы ты хоть один пост в треде прочитал, дошло бы, что все было чуть сложнее, чем тупо кривое имя файла. Таким образом твое глубокомысленное замечание характеризует тебя как дебила, который в очередной раз ничего не понял и влез лицом поторговать.
f13nd, А зачем мне читать, в скрипт токен маркер добавить error_" и автоматикой банить автора темы. Твоё мнение - ты с кл, я вышел от туда. Ваш ресурс затролил школьник. Тут такое не выйдет. Лучше сказать не пройдёт.