Sowas mein ich mit Wrapper:
Test.asm:
Code:
format PE GUI 4.0
entry start
include 'win32a.inc'
section '.code' code readable executable
start:
; hole momentane prozess id
call [GetCurrentProcessId]
push 10
push _pid
push eax
call [itoa]
add esp,0Ch
; gebe vollständige commandline aus
push MB_OK
push 0
push _cmdline
push 0
call [MessageBox]
; starte prozess und warte auf rückgabewert
mov [_si.cb],sizeof.STARTUPINFO
xor eax,eax
push _pi
push _si
push eax
push eax
push eax
push eax
push eax
push eax
push _cmdline
push eax
call [CreateProcess]
push -1
push [_pi.hProcess]
call [WaitForSingleObject]
sub esp,4
push esp
push [_pi.hProcess]
call [GetExitCodeProcess]
mov eax,[esp]
add esp,4
; zeige rückgabewert an
push eax
push _x64
push _fmt
push _buf
call [wsprintf]
add esp,0Ch
push MB_OK
push 0
push _buf
push 0
call [MessageBox]
; hole modul adresse via getmodulehandle
push _ntdll
call [GetModuleHandle]
; und zeige sie an
push eax
push _x86
push _fmt
push _buf
call [wsprintf]
add esp,10h
push MB_OK
push 0
push _buf
push 0
call [MessageBox]
push 0
call [ExitProcess]
section '.data' data readable writeable
_x64 db 'x64',0
_x86 db 'x86',0
_cmdline db 'Getx64Base.exe ntdll.dll '
_pid rb 11
_fmt db '%s ntdll: %.8X',0
_ntdll db 'ntdll.dll',0
_buf rb 256
_pi PROCESS_INFORMATION
_si STARTUPINFO
section '.idata' import data readable
library kernel32,'KERNEL32.DLL',\
user32,'USER32.DLL',\
msvcrt,'MSVCRT.DLL'
include 'api\kernel32.inc'
include 'api\user32.inc'
import msvcrt,\
itoa,'_itoa'
Getx64Base.asm:
Code:
format PE64 GUI 5.0
entry start
include 'win64a.inc'
TH32CS_SNAPMODULE = 8
MAX_MODULE_NAME32 = 255
struct MODULEENTRY32
dwSize rd 1
th32ModuleID rd 1
th32ProcessID rd 1
GlblcntUsage rd 1
ProccntUsage rd 2
modBaseAddr rq 1
modBaseSize rd 2
hModule rq 1
szModule rb MAX_MODULE_NAME32+1
szExePath rb MAX_PATH
rd 1
ends
section '.code' code readable executable
start:
sub rsp,8*(4+1)
call [GetCommandLineW]
lea rdx,[argc]
mov rcx,rax
call [CommandLineToArgvW]
mov [rsp+8*4],rax
or rcx,-1
cmp [argc],3
jnz .fin
lea rsi,[rax+8]
mov rcx,[rsi+8]
call [wtoi]
mov rdi,[rsi]
mov rsi,[rsi]
mov rdx,rdi
mov ecx,eax
.unicode_to_ascii:
lodsw
stosb
test al,al
jnz .unicode_to_ascii
call GetDllBase
mov rcx,rax
.fin:
mov rbx,rcx
mov rcx,[rsp+8*4]
call [LocalFree]
mov rcx,rbx
call [ExitProcess]
proc GetDllBase pid,dll
push r12
a = 2 ; number of pushed registers
b = 4 ; number of qwords reserved for API
c = sizeof.MODULEENTRY32 ; stack frame in bytes
d = (c+7)/8 ; stack frame in qwords
e = (a+b+d+1) and 1 ; alignin stack 16
sub rsp,8*(b+d+e)
virtual at rsp+8*4
me32 MODULEENTRY32
end virtual
mov [dll],rdx
mov edx,ecx
mov ecx,TH32CS_SNAPMODULE
call [CreateToolhelp32Snapshot]
test rax,rax
je .err
mov r12,rax
mov [me32.dwSize],sizeof.MODULEENTRY32
lea rdx,[me32]
mov rcx,rax
call [Module32First]
test eax,eax
je .close
.compare:
lea rdx,[me32.szModule]
mov rcx,[dll]
call [strcmpi]
test eax,eax
je .found
lea rdx,[me32]
mov rcx,r12
call [Module32Next]
test eax,eax
je .close
jmp .compare
.found:
mov rcx,r12
call [CloseHandle]
mov rax,[me32.modBaseAddr]
jmp .fin
.close:
mov rcx,r12
call [CloseHandle]
.err:
xor eax,eax
.fin:
add rsp,8*(b+d+e)
pop r12
ret
endp
section '.data' data readable writeable
argc rd 1
section '.idata' import data readable
library kernel32,'KERNEL32.DLL',\
shell32,'SHELL32.DLL',\
msvcrt,'MSVCRT.DLL'
include 'api\kernel32.inc'
import shell32,\
CommandLineToArgvW,'CommandLineToArgvW'
import msvcrt,\
strcmpi,'_strcmpi',\
wtoi,'_wtoi'
Exen sind angehängt.
Quote:
|
Originally Posted by Mi4uric3
Ich ändere mit Cheat Engine eine Routine in der NtDll an die der Prozess selbst nicht rankommt. Nur so wird der gewünschte Effekt erreicht. Ändere ich es in der NtDll, an die der 32Bit Prozess selbst auch drankommt, tritt der gewünschte Effekt nicht auf.
|
Um was für eine Funktion und Änderung handelt es sich denn? Weiß nämlich immer noch nicht genau, was du meinst.
Handelt es sich z.B. um irgendwelche CRC-Checks, weswegen du die Funktionen in der 32-bit ntdll nicht direkt verändern kannst?
Quote:
|
Originally Posted by Mi4uric3
Das wichtige dabei ist, dass nicht der Prozess selbst diese Funktion nutzt, sondern ein Externer, welcher scheinbar die 64-Bit Version direkt nutzt.
|
Wie geschrieben, die 32-bit Funktionen sind nur Wrapper für die eigentlichen 64-bit Funktionen. Ein 32-bit Syscall ist nur ein Pseudo-Syscall, der in Wirklichkeit entweder zum 64-bit Äquivalent führt, wo dann der eigentlich Syscall ausgeführt wird, der in den Kernelmode wechselt, oder nochmals zu einem diesmal 64-bit Wrapper, der dann erst noch Änderungen vornimmt.
PS:
Mit "TH32CS_SNAPMODULE32 ist unter 32-bit undefiniert" war gemeint, dass es unter x64 die Möglichkeit gibt, entweder 32-bit oder 64-bit Module zu enumerieren.
Unter x86 liefert TH32CS_SNAPMODULE von sich aus 32-bit Module zurück, TH32CS_SNAPMODULE32 ist undefiniert und sowas wie TH32CS_SNAPMODULE64 gibt es nicht.
Edit:
Quote:
|
Originally Posted by tnd0
Edit: Also ja du findest sie zwar, sie ist gemapped aber jeder zugriff darauf endet in einer AV oder sogar GPF. D.h. sie ist zwar augenscheinlich da, aber weder der Prozess an sich noch ein externer Prozess können damit etwas anfangen, es sei denn man sucht nach alternativen ein Programm unsauber und schnell zu beenden.
|
Nein, wieso sollte man darauf nicht zugreifen können?
Wenn eine 64-bit Dll in Reichweite gemappt wird, und 32-bit Code enthält, kann sie ganz normal ausgeführt werden. Wenn sie 64-bit Code enthält, kannst du die CPU in den x64 Mode switchen und den 64-bit Code ganz normal ausführen.
Wie würde der 32-bit Emulator von Windows sonst funktionieren, wenn jeder Zugriff eine Exception auslösen würde?