Writing a patch in ASM *SOLVED*

Having problems with a specific game or application? Post your problems here!

Re: Writing a patch in ASM

Postby Akuma » 2019-11-09 @ 14:45

ripsaw8080 wrote:The most obvious issue is that INT 16 is not "unhooked" before the program terminates; but that would only causes a crash after termination when the program's memory block is released, leaving the INT 16 handler code likely to be overwritten by the next program executed.

So next program hangs because it cannot return ? Or next program hangs because it waits on the former iret ?


ripsaw8080 wrote:A more subtle issue is that INT 21/35 is changing the value of ES, and INT 21/4B uses ES:BX as a pointer to the child program's parameter block. So, you should have a PUSH CS / POP ES or so after the ES value has been stored in memory.

I will look into this :D

ripsaw8080 wrote:Those are the issues that I notice at a glance, not necessarily the only issues.

BTW, when the subject matter is applicable to DOS programming in general and not just for DOSBox, such topics are best posted in Milliways. ;)


I have no problem if the thread gets moved to where it belongs, but I cant do this myself.


cyclone3d wrote:What about using one of those old DOS Game cheater programs that you load up before your game. Then you load the game and press a hotkey sequence and it drops to the game cheater and lets you edit memory values and then go back to the game.

Generally used for changing lives, ammo, etc, but I would think it would work for patching as well.

I think some of them might have let you save profiles.. don't remember though. I haven't used one in years.


I can make it work all sorts of ways, but I wanted to do this in assembly. Thanks though :D
Akuma
Newbie
 
Posts: 80
Joined: 2019-7-24 @ 14:47

Re: Writing a patch in ASM

Postby BloodyCactus » 2019-11-09 @ 15:00

Akuma wrote:
ripsaw8080 wrote:The most obvious issue is that INT 16 is not "unhooked" before the program terminates; but that would only causes a crash after termination when the program's memory block is released, leaving the INT 16 handler code likely to be overwritten by the next program executed.

So next program hangs because it cannot return ? Or next program hangs because it waits on the former iret ?


no, the INT 0x16 now points into trash so when its called, system hangs. you need to re-hook it to its original value before you quit your app
--/\-[ Stu : Bloody Cactus :: http://kråketær.com :: http://mega-tokyo.com ]-/\--
User avatar
BloodyCactus
Oldbie
 
Posts: 946
Joined: 2016-2-03 @ 13:34
Location: Lexington VA

Re: Writing a patch in ASM

Postby pantercat » 2019-11-09 @ 20:13

Well, this is not my code ;)

I have written:

Code: Select all
lea bx, EXEC_INFO


and not:

Code: Select all
mov bx, EXEC_INFO


LEA != MOV.

LEA (or PUSH and POP, as ripsaw8080 said) should eliminate 2nd issue. Maybe with nasm you must write:

Code: Select all
lea bx, [EXEC_INFO]


But well, I'm not an expert, but if you want to use my code as a base, my advice is: compile my code with no modifications first. My code follows A86 syntax, so get A86, put A86.COM and A86.LIB and WHATEVER.ASM in the same directory as "La Colmena CGA/EGA/Hercules" and compile with:

Code: Select all
A86 WHATEVER.ASM


Then run WHATEVER.COM and when you see it works, then have fun modifying it as much as you want. But remember: I'm just a learner. :)

PS: make sure you've La Colmena CGA/EGA/Hercules/VGA-16 version and NOT VGA-256 version. The bytes to modify will be in different memory addresses.
pantercat
Newbie
 
Posts: 47
Joined: 2018-9-06 @ 17:22

Re: Writing a patch in ASM

Postby ripsaw8080 » 2019-11-09 @ 20:20

LEA BX loads the effective address into BX rather than the value at that address, it does not change ES. LES BX would change ES, but it is not really applicable in this case, so the push/pop is the simple solution.
User avatar
ripsaw8080
DOSBox Author
 
Posts: 4434
Joined: 2006-4-25 @ 23:24

Re: Writing a patch in ASM

Postby pantercat » 2019-11-10 @ 00:04

I see why ES should be preserved, but even if ES is destroyed, the loader works nevertheless. Even if I comment entire EXEC_INFO it still works :confused: , so I'm leaning toward DOSBox doing some magic and requiring only DS:DX pointing to the ASCIIZ filename. I bet this wouldn't end well in pure DOS :lol:

Anyway, Akuma, here is a revised full source of the LOADER. Thank you all for your comments.

Code: Select all
;; A86 LOADER.ASM
;; La Colmena CGA/EGA/Hercules/VGA-16 loader

SIZE EQU 1024
OVERLAY segment para 'code'
        assume cs:OVERLAY, ds:OVERLAY
        org 100h

START: jmp INITCODE

OLDINT dw 0,0

NEWINT proc far
    cmp ah, 1
    jnz EXIT

    cmp Word Ptr [0097], 0d75h
    jnz EXIT

    mov Word Ptr [0097], 9090h

EXIT:
    jmp DWord Ptr cs:[OLDINT]
NEWINT endp

INITCODE:
    mov sp, SIZE
    mov bx, SIZE/16
    mov ah, 4ah
    int 21h

    mov ax, 3516h
    int 21h
    mov OLDINT[0], bx
    mov OLDINT[2], es

    push cs
    pop es

    mov ax,2516h
    lea dx, NEWINT
    int 21h

    lea bx, EXEC_INFO
    mov DWord Ptr [bx], 0
    mov DWord Ptr [bx+2], 80h
    mov Word Ptr [bx+4], cs
    mov Word Ptr [bx+6], 5ch
    mov Word Ptr [bx+8], cs
    mov Word Ptr [bx+0ah], 6ch
    mov Word Ptr [bx+0ch], cs

    lea dx, FILENAME
    mov ax, 4b00h
    int 21h

    mov dx, OLDINT[0]
    mov ds, OLDINT[2]
    mov ax,2516h
    int 21h

    push cs
    pop ds
    mov ax, 4c00h
    int 21h

FILENAME    db "COLMENA.EXE",0
EXEC_INFO   db 22 DUP (0)

OVERLAY ends

end START


Keep in mind that this instruction:

Code: Select all
mov Word Ptr [0097], 9090h


is MOVing bytes in DS:[0097]. It's ok in this case, because when mov is executed the bytes you want to patch are in DS:[0097]. But this is not always true. You usually have to figure out the segment where you want to patch looking at the values that were pushed on the stack. You can do something like:

Code: Select all
push bp
mov bp, sp
push es
push ax
mov ax,[bp+6h]  ; more info later
mov es, ax

cmp Word Ptr es:[032b], 0374h
jne ALREADYPATCHED

mov Word Ptr es:[032b], 03ebh

ALREADYPATCHED:
pop ax
pop es
pop bp
...
EXIT:
    jmp DWord Ptr cs:[OLDINT]
NEWINT endp


Hint: you can change data view to SS:BP (DOSBox debugger -> d ss:bp)

but maybe it's quicker just to put some instructions like:
mov ax,[bp]
mov ax,[bp+2h]
mov ax,[bp+4h]
mov ax,[bp+6h]
...

and step into them looking at AX value.

Let's say you're looking for segment where bytes 74 03 are. Let's say you step in mov ax,[bp+6h] and AX=03C0. You already know the offset, say it's 032b, so you'll go to 3c0:32b (DOSBox debugger -> d 3c0:32b) and if you see 7403 congrats, you have found the segment pushed on the stack, you can code mov ax,[bp+6h]
Last edited by pantercat on 2019-11-10 @ 11:06, edited 1 time in total.
pantercat
Newbie
 
Posts: 47
Joined: 2018-9-06 @ 17:22

Re: Writing a patch in ASM

Postby ripsaw8080 » 2019-11-10 @ 02:52

Well, it's true that few games care about finding environment variables, but the most significant potential problem with a bad pointer to the parameter block comes when the child program releases its environment block on termination. The effect might not be noticeable (e.g. crash, hang, or error) depending on what happens to be in memory where ES:BX is pointing, but arbitrary behavior should be avoided of course. ;)
User avatar
ripsaw8080
DOSBox Author
 
Posts: 4434
Joined: 2006-4-25 @ 23:24

Re: Writing a patch in ASM

Postby akuma667 » 2019-11-10 @ 11:54

Sorry guys, I had an unfortunate accident, my password database got corrupted amongst other things
and I have no backup :blush: No important data is lost except for that. *phew*

So I will contact an admin and ask how to go about this, just letting everyone know
as I appreciate your feedback. If you PM me and I don't respond, this is why.

This might take a while, we'll see.
akuma667
Newbie
 
Posts: 5
Joined: 2019-11-10 @ 11:42

Re: Writing a patch in ASM

Postby akuma667 » 2019-11-11 @ 12:46

I think I found the problem, its probably me and my coding but I have that feeling...

When I convert:
Code: Select all
A86: jmp dword ptr cs:[INTORIG] 
into
NASM: jmp dword [cs:INTORIG]


After compiling:
Code: Select all
A86: jmp dword ptr cs:[INTORIG]  ---> 2E FF 2E 66 01
to
NASM: jmp dword [cs:INTORIG]   ---> 2E 66 FF 26 67 01


When I convert:
Code: Select all
A86: jmp dword ptr cs:[INTORIG] 
into
NASM: jmp WORD [cs:INTORIG]


After compiling:
Code: Select all
A86: jmp dword ptr cs:[INTORIG]  ---> 2E FF 26 66 01
to
NASM: jmp WORD [cs:INTORIG]   ---> 2E FF 2E 66 01


When I manually patch 2E into 26 , all starts working :D
(because it changed WORD into DWORD and gets the same length as the A86 compiled version.

So is this my syntax error, or is this a bug ?
akuma667
Newbie
 
Posts: 5
Joined: 2019-11-10 @ 11:42

Re: Writing a patch in ASM

Postby BloodyCactus » 2019-11-11 @ 13:03

the "2E 66 FF 26 67 01" first 0x66 is a 32bit size override.

I use "jmp far [cs: xxxxxx]" in nasm instead of jump dword
--/\-[ Stu : Bloody Cactus :: http://kråketær.com :: http://mega-tokyo.com ]-/\--
User avatar
BloodyCactus
Oldbie
 
Posts: 946
Joined: 2016-2-03 @ 13:34
Location: Lexington VA

Re: Writing a patch in ASM

Postby akuma667 » 2019-11-11 @ 13:39

BloodyCactus wrote:the "2E 66 FF 26 67 01" first 0x66 is a 32bit size override.

I use "jmp far [cs: xxxxxx]" in nasm instead of jump dword

That's it! :D

My syntax error it was: when using 'jmp far [cs:xxxxx[' all works like it should.
I will mark this thread solved when I regain access to my account.

Thanks BloodyCactus, you just gave me the last piece of the puzzle :D
akuma667
Newbie
 
Posts: 5
Joined: 2019-11-10 @ 11:42

Re: Writing a patch in ASM

Postby akuma667 » 2019-11-13 @ 10:07

pantercat wrote:Well, this is not my code ;)

I have written:
Code: Select all
lea bx, EXEC_INFO


and not:
Code: Select all
mov bx, EXEC_INFO


LEA != MOV.

Actually it is your code ;)

You have written:
Code: Select all
lea bx, EXEC_INFO


and I converted it to:
Code: Select all
mov bx, EXEC_INFO


A86:LEA != A86:MOV , but A86:LEA == NASM:MOV following http://left404.com/2011/01/04/convertin ... to-nasm-3/ and since I get the exact binary this way its a proper conversion afaict.

But the code was extremely helpful, thanks again for that :D
.
akuma667
Newbie
 
Posts: 5
Joined: 2019-11-10 @ 11:42

Re: Writing a patch in ASM

Postby pantercat » 2019-11-13 @ 11:04

You're right. In nasm data labels are automatically treated as addresses, unless they are enclosed in square brackets.

Thanks for pointing it and happy coding :-D
pantercat
Newbie
 
Posts: 47
Joined: 2018-9-06 @ 17:22

Re: Writing a patch in ASM *SOLVED*

Postby Akuma » 2019-11-27 @ 10:47

Just out of curiosity what if the address of the patch falls outside the max offset of FFFFh ?
eg: cs=0 segment=cs offset=10000h

You have to point the segment value to a location where the offset can reach it.
How would one make this work :confused: ?
Akuma
Newbie
 
Posts: 80
Joined: 2019-7-24 @ 14:47

Re: Writing a patch in ASM *SOLVED*

Postby BloodyCactus » 2019-11-27 @ 13:21

change the ds or such and rebase from it
--/\-[ Stu : Bloody Cactus :: http://kråketær.com :: http://mega-tokyo.com ]-/\--
User avatar
BloodyCactus
Oldbie
 
Posts: 946
Joined: 2016-2-03 @ 13:34
Location: Lexington VA

Re: Writing a patch in ASM *SOLVED*

Postby Akuma » 2019-11-28 @ 21:10

I searched and read some stuff today but its still confusing.
So I need to assign a base address to ds ?
I want cs+10000h, so 1000h/10h=1000h

mov bx,1000h
mov ds,bx ?
mov byte [ds:1h],'A' :confused:
Akuma
Newbie
 
Posts: 80
Joined: 2019-7-24 @ 14:47

Re: Writing a patch in ASM *SOLVED*

Postby BloodyCactus » 2019-11-29 @ 16:47

you need to know its posistion from a register value called in your ISR.

so something like

push ds
mov ax,ds
add ax,0x1000
mov ds,ax
mov b[0x0001] = 'A'
pop ds
--/\-[ Stu : Bloody Cactus :: http://kråketær.com :: http://mega-tokyo.com ]-/\--
User avatar
BloodyCactus
Oldbie
 
Posts: 946
Joined: 2016-2-03 @ 13:34
Location: Lexington VA

Previous

Return to DOSBox Games/Apps

Who is online

Users browsing this forum: No registered users and 2 guests