Problem mit asm in c++

So mein erster post hier und stell schon gleich dumme Fragen ^^.

Also ich schreib ne dll in c++ und hab folgendes Prob ich will folgenden asm code umsetzen:

Code:
0066618F: 
mov edx, [esi] 
mov eax, 00000064 
jmp 006661A7

hier ein versuch mit memcpy:

Code:
memcpy((void*)0x0066618F, (void*)PG, 7);

wobei PG: unsigned long PG[]={0x8B,0x16,0xB8,0x64,00,00,00}; //die AOB von der asm anweisung

also wenn ich den 1:1 in c++ umsetze mit _asm{} dann meckert der bei 0066618F: und bei jmp (ungültiger operand). ich möchte aber den code genau an der adresse oben ausführen. Ich habs schon mit memcpy versucht indem ich die aobs versucht hab zu überschrieben aber das klappt auch nich so ganz. Mir gehen langsam die ideen aus, hoffentlich könnt ihr mir helfen.


-Kankomi
 
Sag mal, was soll denn das werden, wenn es fertig ist? Eine Endlosschleife? Adressen kann man nicht so einfach einfügen wie du dir das vorstellst. "0066618F:" ist nur eine einfache Sprungmarke und die wird nach dem kompilieren wahrscheinlich nicht bei 0066618F liegen. Wenn du "jmp 006661A7" schreibst, dann muss es auch irgendwo eine Sprungmarke 006661A7: geben. Wenn du was ganz Verrücktes machen willst und mitten in deinen vorigen Befehl springen willst geht das nur z.B. mit "db 0EBh,0FDh". (EB für kurzer Sprung, FD Zweierkomplement für -3)
 
vielleicht hätt ich etwas genauer schreiben sollen die dll die ich schreibe soll nachher in ein prozess injected werden und da per hotkey den asm code ausführen.

ich hab in meinem 'opfer' an der adresse 0066618F: folgenden asm code:
Code:
mov edx,[esi]
mov eax,00000064
jmp 006661a7

den ich in:

Code:
mov edx, [esi] 
mov eax, 00000064 
jmp 006661A7

umschreiben will
 
Versuch mal folgendes:
Code:
beginn: 
mov edx, [esi] 
mov eax, 00000064 
jmp beginn+0x18

Allerdings musst du damit rechnen, das die größe des nachfolgenden codes nicht unbedingt konstant ist.
(Wenn ich das richtig Sehe (bzw ich mich nicht verrechnet habe), überspringst du ein paar Bytes nach dem jmp)

---

mist zu langsam :D
Gut, durch die neue Situation ist der obrige code unbrauchbar :)

Was stimmte denn mit memcpy nicht?? (wobei ich den Sprung in dem Array nicht widerfinde...)
 
also der original aob von dem original asm code sieht so aus:

FF 50 04 FF B0 30 02 00 00

der soll nachdem obigen code dann so aussehen:

8B 16 B8 64 00 00 00 EB 0F

mit der memcpy funktion von oben sieht aber meiner dann so aus:

8B 00 00 00 16 00 00 EB 0F
 
JMPs auf absolute adressen, ohne viel ausrechnen zu müssen:
Code:
MOV REGISTER,ADRESSE
JMP REGISTER
oder, falls man keine Registerwerte überschreiben möchte:
Code:
push ADRESSE
ret
ansonsten sind gewöhnliche JMPs und CALLs, entgegen der Schreibweise, nur indirekt.

bsp aus einer Anwendung:
Code:
004D7BFD   |. /75 1C                      JNZ SHORT auxilium.004D7C1B
das ist ein SHORT JMP, Opcode 75 stehet für JNZ und 1C steht für die Entfernung (aktuelle Adresse+ Opcodelänge + 1C =4D7BFD+2+1C=4D7C1B )

Dasselbe bei Calls und "Long JMPs". Daher kann man nicht so einfach JMP zu einem Label im Code schreiben und hoffen, dass es im Compiler/Assembler so wie gedacht klappt ;)

Was memcopy Problem angeht: normalwerweise ist es nicht so wählerisch - sprich, entweder klappt es komplett, oder gar nicht. Sicher, dass da kein zweiter Patcher die Adresse überschreibt? Und dass zum Schreibzeitpunkt im Array iimmer noch das steht, was gewollt ist?
 
Was memcopy Problem angeht: normalwerweise ist es nicht so wählerisch - sprich, entweder klappt es komplett, oder gar nicht. Sicher, dass da kein zweiter Patcher die Adresse überschreibt? Und dass zum Schreibzeitpunkt im Array iimmer noch das steht, was gewollt ist?

nein nicht wirklich da ich meine dll nicht wirklich debuggen kann, ich injecte die mit einem externen prog und wenn ich das mit debug funktion von vc versuch klappt das nich irgendwie(da tut sich nix).

wenn ich deinen code mal einfpge also so:

Code:
_asm
		   {
				push 0x0066618F
				ret
				mov edx, [esi] 
                                mov eax, 0x00000064 

	            }

dann crasht mein 'opfer' prog

ich möchte auch nochmal betonen das es mir darum geht den vorhandenen code zu überschreiben. Also der code ab der adresse 0066618F soll überschrieben werden und dann soll das da stehn wie oben. Der Code oben is aus einem cheatenginescript den ich jetzt als dll trainer umschreiben möchte sodass ich die CE nicht mehr brauche.


btw ich bin fasziniert wie gut hier einem geholfen wird hab schon bei vielen Foren nach diesem problem nachgefragt aber überall wird man entweder mit dummen kommentaren überhäuft oder man kriegt nur völlig nutzlose posts.

In diesem Sinne vielen Dank und weiter so!!!
 
Zum Debuggen: das ist immer immens hilfreich ;)
Wie gut kennst Du OllyDbg?

Schreibe in der DLL vor MEMCOPY ein while(true)Schleife oder
Code:
_asm 
{ myLabel: jmp myLabel}
Der Sinn ist, dass der Loader die DLL injekted, diese ganz normal arbeitet und erst vor MEMCOPY in eine Schleife geht. Nun kannst Du die Anwendung im Debugger attachen und schauen. Bei OllyDbg wäre das "File->Attach" und dann "Debug->Pause". Dann landest Du direkt in der Schleife, überschreibst die mit NOPs und guckst, ob im Array immer noch die richtigen Opcodes stehen und was sonst noch schiefläuft.

wenn ich deinen code mal einfpge also so:
so wie es da steht, heßt es sinngemäß:
Code:
jmp 0x0066618F
mov edx, [esi] 
 mov eax, 0x00000064

Mein Tipp: nimm den Patch als Bytearray - bevor man zu viele Verrenkungen wegen der Compilereigenarten und _asm macht.
D.h z.B in OllyDbg kann man seinen Patch schrieben, die Zeilen markieren und Rechtsklick->Binary->Binary copy die Bytes kopieren.


Wegen Probleme beim Überschreiben: auch wenn es im Debugger direkt klappt, muss man je nach dem den Speicher auf "beschreibbar" setzen.

VirtualProtect, PAGE_EXECUTE_READWRITE
http://msdn2.microsoft.com/en-us/library/aa366898(VS.85).aspx
sollte da helfen

paar Beispiele zur Anwendung:
(C++) "Bot"-Programm für Game schreiben.
VirtualProtectEx() schlägt immer fehl, wieso???

PS: wäre hilfreich, wenn Du ein paar Worte zu Deinem Kenntnisstand diesbezüglich sagst. Also Asm, OllyDbg, C++ - spart Zeit, wenn man nichts doppelt/umsonst erklären muss und Dein Vorteil wäre, dass die Antworten nicht zu kompliziert/zu vereinfach ausfallen ;)
 
also zu meinem kenntnisstand: ich studiere Informatik(2.semsester) also c++ ist mir schon ein begriff obwohl in diesem zusammenhang neu, asm: naja ich weiss was es ist und wozu es da ist FLAGS jmp mov push pop stack ist mir ein begriff aber weiter nicht, ollydbg kenn ich vom sehn^^ also ich hab halt bis jetzt mit ner Cheat engine gearbeitet was im prinzip ja fast daselbe ist nur nich so detailreich.


so das mit dem ollydbg hab ich mal ausprobiert und sowie ich das verstehe meinst du das ich die bytes mit memcpy patchen soll, oder? Mir wär das ganze auch lieber so weil mit _asm is mir das zu instabil
 
ich studiere Informatik(2.semsester)
Nana, das zweite Semester hat noch nicht angefangen ;).

so das mit dem ollydbg hab ich mal ausprobiert und sowie ich das verstehe meinst du das ich die bytes mit memcpy patchen soll, oder? Mir wär das ganze auch lieber so weil mit _asm is mir das zu instabil
Jep. Direktkopie.
Den Patch im Debugger schreiben und testen - dann kann man die Bytes daraus kopieren und direkt verwenden.
Es gibt da auch öfters Bytes zu Array Konverter für verschiedene Sprachen.
Ist zwar auch möglich mit _asm das Ziel zu erreichen, erfordert aber nicht zuletzt detailierte Kenntnisse, was aus den Asm-Zeilen am Ende wird.

PS: warum DLL injekten, anstatt direkt im Speicher zu patchen? OpenProcess und WriteProcessMemory als APIs sollten genügen.

Ansonsten: was sagt Olly beim Debuggen ? Oder lass dir im Code den Arrayinhalt direkt nach memcpy ausgeben.
 
naja das problem ist das ich das für das Spiel MapleStory mache und ich ein problem mit debuggern kriege weil die detected werden deswegen wollt ich das als dll inject machen außerdem ist das viel bequemer(wenns mal funzt)
außerdem gehts nicht nur um das spiel sondern viel mehr darum das ich was lerne^^

PS: warum DLL injekten, anstatt direkt im Speicher zu patchen? OpenProcess und WriteProcessMemory als APIs sollten genügen.

ähem kommt bei writeprocessmemory nicht irgendwie daselbe raus wie bei memcpy?

Nana, das zweite Semester hat noch nicht angefangen Augenzwinkern .

na komm schon, nächste woche gehts los ^^

das mit ollydbg versteh ich net ganz wenn ich das so mache wie du gesagt hast lande ich bei
Code:
7C911231   C3               RETN
7C911232   8BFF             MOV EDI,EDI
7C911234   90               NOP
7C911235   90               NOP
7C911236   90               NOP
7C911237   90               NOP

weis net was ich damit anfange soll. hab _asm{jump: jmp jump} vor mein memcpy gesetzt.

wie würde denn das patchen codetechnisch dann bei dir aussehen?
 
hem kommt bei writeprocessmemory nicht irgendwie daselbe raus wie bei memcpy?
WriteProcessMemory kann auch in fremden Prozessen schreiben.

das mit ollydbg versteh ich net ganz wenn ich das so mache wie du gesagt hast lande ich bei
Ja, irgendwie muss man aber schauen, was da nun nicht klappt:
z.B vor memcpy eine MessageBox anzeigen, um erstmal sicher zu gehen, dass der Code überhaupt ausgeführt wird und zweitens: während die MessageBox angezeigt wird, kann man wieder im Debugger attachen und einen Breakpoint auf memcpy-Aufruf machen.
Versuche mal den Speicher an der Patchstelle vor memcpy auszulesen und auszugeben und dann danach - das kann man im code machen (MsgBox oder Filedump).


debuggern kriege weil die detected werden deswegen wollt ich das als dll inject machen außerdem ist das viel bequemer(wenns mal funzt)
technisch gesehen ist es kein Unterschied, ob ein Loader eine DLL injeziert oder direkt den Patch schreibt ;)

wie würde denn das patchen codetechnisch dann bei dir aussehen?
Code:
      .386                      
      .model flat, stdcall      
      option casemap :none      

;     include files
;     ~~~~~~~~~~~~~
      include \masm32\include\windows.inc
      include \masm32\include\masm32.inc
  
      include \masm32\include\user32.inc
      include \masm32\include\kernel32.inc
   
     
;     libraries
;     ~~~~~~~~~
      includelib \masm32\lib\masm32.lib
    
      includelib \masm32\lib\user32.lib
      includelib \masm32\lib\kernel32.lib    
   
      
      
    
     
; ?????????????????????????????????????????????????????????????????????
.code
jmp @f
  hInstance dd 0
  cmname db "cRz - LoaderMe#1.exe",0  
  error db "Fehler!",0
  hProcess dd 0
 oldprotection dd 0
  ID dd 0
  startup STARTUPINFO<>
  prozinfo PROCESS_INFORMATION <>


@@:
start:   
      
main: 
      invoke GetModuleHandle,NULL
      mov hInstance,eax
      invoke CreateProcess,addr cmname,0,0,0,FALSE,0,0,0,addr startup,addr prozinfo
      invoke Sleep,2000
      
      
        mov eax,prozinfo.dwProcessId
        invoke OpenProcess,PROCESS_ALL_ACCESS,FALSE,eax
        .if eax!=0
          mov hProcess,eax
                jmp @f                 
                   byte1 db 085h               
                   PATCH equ 41afc6h
                   byteswritten dd 0 
                @@:
        	invoke VirtualProtectEx,hProcess,PATCH,10,PAGE_EXECUTE_READWRITE,addr oldprotection
                invoke WriteProcessMemory,hProcess,PATCH,addr byte1,1,addr byteswritten                
                
        .else
        	invoke MessageBox,0,addr error,addr error,MB_ICONERROR
        .endif     
      invoke ExitProcess,eax

end start

Code:
      .386                      
      .model flat, stdcall      
      option casemap :none      

;     include files
;     ~~~~~~~~~~~~~
      include \masm32\include\windows.inc
      include \masm32\include\masm32.inc
  
      include \masm32\include\user32.inc
      include \masm32\include\kernel32.inc
      include \masm32\include\psapi.inc
      includelib \masm32\lib\psapi.lib
      include \masm32\include\advapi32.inc
      includelib \masm32\lib\advapi32.lib
;     libraries
;     ~~~~~~~~~
      includelib \masm32\lib\masm32.lib
    
      includelib \masm32\lib\user32.lib
      includelib \masm32\lib\kernel32.lib    
   
     
     
; ?????????????????????????????????????????????????????????????????????
.code


start:
	  jmp @f
	  hInstance dd 0
          hSnapshot dd 0
	  cmname db "Patrick.exe",0
	  error db "Fehler!",0
	  hExplorer dd 0
	  hProcess dd 0
	  ID dd 0	 	 
	  oldprotection dd 0
	  uProcess	PROCESSENTRY32	<>


	@@:
   ;   invoke AddDebugPrivileges
      invoke GetModuleHandle,NULL
      mov hInstance,eax
       invoke	CreateToolhelp32Snapshot, TH32CS_SNAPPROCESS, 0	
	 mov hSnapshot,eax
	 
	 .if eax!=-1 
	 	mov uProcess.dwSize, sizeof uProcess	 	
	 	invoke	Process32First, eax, ADDR uProcess
	 		
	 	.while eax
	 		lea edi,[uProcess.szExeFile]
	 		
	 		push edi
	 		  lea esi,cmname
	 		  xor ecx,ecx
	 		  compare_loop:
	 		    mov al,byte ptr [edi]
	 		    mov ah,byte ptr [esi]
	 		    .if al==0 || ah==0
	 		        mov eax,uProcess.th32ProcessID
	 		    	mov hExplorer,eax
	 		    	jmp next1
	 		    .endif
	 		    .if al!=ah
	 		        jmp @f
	 		    .endif
	 		    add edi,1
	 		    add esi,1
	 		    jmp compare_loop
	 		    @@:
	 		pop edi	 	
	 		invoke	Process32Next, [hSnapshot], ADDR uProcess	
	 	.endw	
	  next1:
	  invoke CloseHandle,hSnapshot
	 .endif	
         
      ;warten

      pushad
      invoke Sleep,1000
      popad
      
       
        invoke OpenProcess,PROCESS_ALL_ACCESS,FALSE,hExplorer
        .if eax!=0
          mov hProcess,eax
         invoke VirtualProtectEx,hProcess,77E41BBDh,1000h,PAGE_EXECUTE_READWRITE,addr oldprotection
        	.if eax!=0
        	     jmp @f                 
                  patch dw 0feebh
                   
                @@:
              invoke WriteProcessMemory,hProcess,77E41BBDh,offset patch,4,addr cmname
              .endif
        .else
        	invoke MessageBox,0,addr error,addr error,MB_ICONERROR
        .endif     
      invoke ExitProcess,eax

; ?????????????????????????????????????????????????????????????????????


; ?????????????????????????????????????????????????????????????????????

; ?????????????????????????????????????????????????????????????????????
AddDebugPrivileges PROC
;**********************

LOCAL tkP:TOKEN_PRIVILEGES
LOCAL hToken  :HANDLE
LOCAL CurProc :DWORD
.data
   debug  db "SeDebugPrivilege",0
.code


invoke GetCurrentProcess
mov CurProc,eax
lea eax,hToken

invoke  OpenProcessToken,CurProc,TOKEN_ADJUST_PRIVILEGES,eax

lea eax,tkP.Privileges[0].Luid
invoke LookupPrivilegeValue,NULL,addr debug,eax

mov [tkP.PrivilegeCount],1
mov tkP.Privileges[0].Attributes,SE_PRIVILEGE_ENABLED
lea eax,tkP

invoke AdjustTokenPrivileges,hToken,FALSE,eax,0,NULL,0

invoke CloseHandle,[hToken]
mov eax,0
ret
AddDebugPrivileges ENDP
 ;*

end start
77E41BBD     8BEC                                        MOV EBP,ESP

Aber da sollte es auch genug Loader-Beispiele in C++ geben ;)
 
Ja, irgendwie muss man aber schauen, was da nun nicht klappt:
z.B vor memcpy eine MessageBox anzeigen, um erstmal sicher zu gehen, dass der Code überhaupt ausgeführt wird und zweitens: während die MessageBox angezeigt wird, kann man wieder im Debugger attachen und einen Breakpoint auf memcpy-Aufruf machen.
Versuche mal den Speicher an der Patchstelle vor memcpy auszulesen und auszugeben und dann danach - das kann man im code machen (MsgBox oder Filedump).

ich glaub wir haben da aneinander vorbeigeredet: ich weiss ja was falsch läuft aber ich weis net was ich dagegen machen kann, wie gesagt in diesem bereich bin ich noch grün hinter den ohren^^.

Also ich versuch nochmal zusammenzufassen wie ich vorgehe:

ich hab meine bytes schon ausgelesen die ich patchen will und weiss auch wo die stehen und mit was die überschrieben werden sollen.
Diese Bytes speicher ich so in ein Array:

unsigned long PG[]={0x8B,0x16,0xB8,0x64,00,00,00,0xEB,0x0F};

und dann versuche ich das per memcpy zu patchen:

VirtualProtect(PGHACK, 9, PAGE_EXECUTE_READWRITE, &OldProt);
memcpy((void*)0x0066618F, (void*)PG, 9);
VirtualProtect(PGHACK, 9, OldProt, &OldProt);

wobei hier PGHACK die adresse 0066618F ist.(da wo die bytes wo ich patchen will anfangen).

Die dll wird richtig geladen und memcpy wird auch ausgeführt aber nicht so wie ich das will:

Bytes:
8B 16 B8 64 00 00 00 EB 0F <- So sollte es ausshen bei 0066618F

8B 00 00 00 16 00 00 EB 0F <- aber leider kommt das dabei raus T_T


Das mit MASM hat mich jetzt richtig geschockt, ich dachte du hast oben gemeint das ich das auch mit memcpy patchen kann.

Das mit writeprocessmemory ist das besser oder einfacher? weil ich hab mich halt jetzt scho auf dll injection versteift das es jetzt blöd wär nochmal alles neu zu machen.

Danke das du mich noch nicht aufgegeben hast ;)
 
ich glaub wir haben da aneinander vorbeigeredet: ich weiss ja was falsch läuft aber ich weis net was ich dagegen machen kann, wie gesagt in diesem bereich bin ich noch grün hinter den ohren^^.
Stimmt nur zum Teil ;) - ich finde es eben nützlich, wenn man sich genau ansehen kann, was passiert.

Sonst: erst jetzt fällt mir auf, dass du einen long array hast. Das schaut im Speicher so aus:
Code:
0012FF4C  8B 00 00 00 16 00 00 00 B8 00 00 00 64 00 00 00  ?......¸...d...
0012FF5C  00 00 00 00 00 00 00 00 00 00 00 00 EB 00 00 00  ............ë...
0012FF6C  0F 00 00 00                                      ...
weil long eben 32-Bit Datentyp ist und daher vom Compiler einfach mal 4 bytes genommen werden. Rätselhaft ist nur, warum am Ende des patchs tortzdem EB 0F und nicht 00 stehen. Nimm stattdessen erstmal "unsigned char".
 
Der Fehler liegt bei der Deklaration!
long ist 4Byte groß. d.h. es wird nicht 0x8B, sondern 0x8B,0x00,0x00,0x00 in den Speicher geschrieben.

Richtig währe:
unsigned char PG[]={0x8B,0x16,0xB8,0x64,00,00,00,0xEB,0x0F};

---
Mist, zu spät :)
 
juuuhuuuu danke danke man das es sowas banales immer ist ^^. ich dachte da des so lang ist nehm ich long weil char ist doch kleiner. Naja aber es wär ja viiiiel zu einfach wenn jetzt schon alles funktionieren würde die bytes werden jetzt zwar richtig geschrieben jedoch stürzt jetzt beim aktivieren das prog ab.


Code:
#include "windows.h"
#include <iostream>
using namespace std;

#define NKB 0x0066E4D3

int *PGHACK= (int*)0x0066618F;
unsigned char PG[]={0x8B,0x16,0xB8,0x64,00,00,00,0xEB,0x0F};
DWORD OldProt;


bool EasyDLL(void)
{
	
   MessageBoxA(0,"Trainer succesfully Loaded!", "Kankomi Trainer", 0);
   
   for(;;)
   {
	   Sleep(10);

	   if(GetAsyncKeyState(VK_F12))
	   {
			
		   VirtualProtect(PGHACK, 9, PAGE_EXECUTE_READWRITE, &OldProt);
		   memcpy((void*)0x0066618F, (void*)PG, 9);
		   VirtualProtect(PGHACK, 9, OldProt, &OldProt);
	   

		   MessageBoxA(0, "PG Hack loaded", ".:::1337:::.", 0);
	   }


	   if(GetAsyncKeyState(VK_F11))
	   {
		   *(BYTE*)NKB = 125;
		   MessageBoxA(0, "No Knockback loaded", ".:::1337:::.", 0);

	   }

	   if(GetAsyncKeyState(VK_END))
	   {
		   MessageBoxA(0, "Ejecting...", ".:::1337:::.", 0);
		   Sleep(100);
		   HINSTANCE hMod = GetModuleHandleA("EasyDLL.dll");
		   FreeLibraryAndExitThread(hMod, 0);
	   }
  

   }
   
   return TRUE;
}



BOOL APIENTRY DllMain(HMODULE hModule,DWORD ul_reason_for_call,LPVOID lpReserved)
{
   if (ul_reason_for_call == DLL_PROCESS_ATTACH)
   {
      CreateThread(0, 0, (LPTHREAD_START_ROUTINE)&EasyDLL, 0, 0, 0);
   }
   return true;
}


hier ist mal mein gesamter code.


noch mal vielen dank!!!
 
ich dachte da des so lang ist nehm ich long weil char ist doch kleiner
die Angabe bezieht sich ja auf die einzelnen Elemente. Möchte man Bytes einzeln schreiben, sollte man auch einen Datentyp nehmen, der intern nur durch ein Byte und nicht 4 repräsentiert wird ;)

Bezüglich des Absturzes: und nun? Wenn der Inhalt des Array tatsächlich so geschrieben wird und der Patch wirklich so funktioniert bleiben entweder die Kristallkugel oder der Debugger ;).

Z.B: OllyDbg unter "Options" als Just in time Debugger setzen - wenn das Spiel abstürzt, bietet Olly dann die Option an, es zu öffnen. Dann kurz mal zu der Adresse 0x66618F wechseln und prüfen, ob alles stimmt.
Mögliche Fehlerquellen: man hat doch irgendwas beim Patch vergessen. Oder nicht an die gedachte Speicherstelle geschrieben. Oder gar man patcht dynamisch reservierten Speicher - die bei DLL Injektion unerwarteterweise andere Adresse reserviert.
Also einfach mal versuchen den Fehler einzukreisen.
 
Zurück
Oben