Skyrim - Text in der Console ausgeben

12/27/2011 12:59 vwap#1
Hey, ich versuche gerade per C und Inline ASM einen Text in der Console auszugeben.
Die Funktion habe ich in Olly bereits gefunden:

Code:
PUSH EAX ; /<%s> => OFFSET LOCAL.134
PUSH OFFSET 01257F00 ; |Format = "Script command "%s" not fount."
MOV ECX, DWORD PTR SS:[ARG.1] ; |
PUSH ECX
CALL 00586620
Jetzt die Frage:
Würde diese Umsetzung stimmen?

Code:
void printConsole(char *szText) {
DWORD dwAddress = 0x00586620;

__asm {
   PUSH EAX
   PUSH OFFSET szText
   MOV ECX, DWORD PTR SS:[ARG.1]
   PUSH ECX
   CALL dwAddrss
}
}
Wenn nicht, wäre es sehr freundlich, mir einen Ansatz zu geben.
12/27/2011 14:15 Trollface-#2
Code:
void printConsole(char *szText) {
DWORD dwAddress = 0x00586620;

__asm {
   PUSH EAX
   PUSH OFFSET szText
   [B]MOV ECX, DWORD PTR SS:[ARG.1][/B]
   PUSH ECX
   CALL dwAddrss
}
}

Dürfte eigentlich nicht gehen, weißt du den was ARG.1 ist?
12/27/2011 14:24 vwap#3
ARG.1 ist der übermittelte Text.
Wäre das dann also ".. PTR SS:[szText]"?
12/27/2011 14:43 Ende!#4
ARG.1 ist ein Label, was Olly zur besseren Übersicht einsetzt, um einen Zugriff auf die Parameter der Funktion darzustellen. ARG.1 steht also eigentlich für ebp+8, ARG.2 für ebp+0xC usw., vorausgesetzt natürlich, dass ebp in diesem Fall den für den Stackframe verwendeten Pointer enthält. Welches Register dafür verwendet wird, kann man in den meisten Fällen dem Function-Prologue entnehmen, z.B.:
Code:
push [COLOR="Red"]ebp[/COLOR]
mov [COLOR="Red"]ebp[/COLOR], esp
In diesem Falle wäre ebp das Register, was den Stackframe 'darstellt', was auch in den meisten Programmen der Fall ist.

Was auch immer bei den Calls des Games in EAX und ARG.1 steht, du wirst es ebenfalls übergeben müssen, wenn du möchtest, dass die Funktion korrekt arbeitet. Bei ARG.1 würde ich auf den this-Pointer der Instanz der Console-Klasse tippen, bei EAX ist es ohne mehr umgebenden Code nicht möglich da etwas zu zu sagen (das ist keine Aufforderung mehr Code zu posten, schau dir das lieber selber an).

Wenn du jetzt noch OFFSET weg lässt, sollte das Ganze auch funktionieren :p
12/27/2011 14:55 vwap#5
Danke Ende,
habe das jetzt wiefolgt:

Code:
PUSH EAX
PUSH szText
MOV ECX, DWORD PTR SS:[szText]
PUSH ECX
CALL dwAddress
Du hast gesagt, ich muss auch EAX durch den korrekten Wert ersetzen, nur durch welchen? Und stimmt der Rest nun?

Zu EAX:
Vor dem "PUSH EAX" steht noch "LEA EAX, [LOCAL.134]".
Was bedeutet das denn?
12/27/2011 14:56 MrSm!th#6
Ich bezweifle, dass ARG1 der this-ptr ist, da er zusätzlich noch gepusht wird.
Normalerweise würde er ja nur in ECX gemoved werden.
Ich denke, ECX wird hier einfach als Zwischenspeicher genutzt.

Btw. Funktionszeiger wären hier deutlich lesbarer (wenn du dir den Code später nochmal ansiehst) und angenehmer zu nutzen. Solltest sie anstatt inline ASM nutzen ;O
12/28/2011 01:17 vwap#7
Ich hab jetzt nochmal gesucht, und direkt die Funktion gefunden, die nur für das ausgeben des Textes auf den Bildschirm verantwortlich war.

Code:
CPU Disasm
Address   Hex dump          Command                                  Comments
00405030  /$  55            PUSH EBP                                 ; TESV.00405030(guessed Arg1,Arg2,Arg3)
00405031  |.  8BEC          MOV EBP,ESP
00405033  |.  8B45 10       MOV EAX,DWORD PTR SS:[ARG.3]
00405036  |.  50            PUSH EAX
00405037  |.  8B4D 0C       MOV ECX,DWORD PTR SS:[ARG.2]
0040503A  |.  51            PUSH ECX
0040503B  |.  8B55 08       MOV EDX,DWORD PTR SS:[ARG.1]
0040503E  |.  52            PUSH EDX
0040503F  |.  E8 755DD000   CALL 0110ADB9
00405044  |.  83C4 0C       ADD ESP,0C
00405047  |.  5D            POP EBP
00405048  \.  C3            RETN
Der Stack sieht so aus:
Code:
CPU Stack
Address   Value      ASCII Comments
0018E848  [00404D6A  jM@   ; /RETURN from TESV.00405030 to TESV.00404D6A
0018E84C  /0018E85C  \è   ; |Arg1 = 18E85C
0018E850  |01257E44  D~%  ; |Arg2 = ASCII "SCRIPTS: Script '%s', line %d:
%s"
0018E854  |0018EC8C  Γ   ; \Arg3 = 18EC8C
Habe es nun so versucht: (An Ende! orientiert)
Code:
DWORD dwAddress = ADR_CONSOLE_PRINT;

		__asm {
			MOV EAX, DWORD PTR SS:[EBP + 0x10]
			PUSH EAX
			MOV ECX, DWORD PTR SS:[szText]
			PUSH ECX
			MOV EDX, DWORD PTR SS:[EBP + 0x8]
			PUSH EDX
			CALL dwAddress
			ADD ESP, 0x0C
		}
Crasht leider, was ist denn falsch?