VOGONS


Writing a patch in ASM *SOLVED*

Topic actions

Reply 40 of 44, by BloodyCactus

User metadata
Rank Oldbie
Rank
Oldbie

get rid of memsize equ and replace it with a lable at the bottom of the app

[section .bss]
alignb 16
resw 256
end_app:

then your start code bcomes

mov sp,end_app
mov bx,sp
shr bx,4

--/\-[ Stu : Bloody Cactus :: [ https://bloodycactus.com :: http://kråketær.com ]-/\--

Reply 41 of 44, by Akuma

User metadata
Rank Member
Rank
Member
BloodyCactus wrote on 2021-08-03, 15:34:
get rid of memsize equ and replace it with a lable at the bottom of the app […]
Show full quote

get rid of memsize equ and replace it with a lable at the bottom of the app

[section .bss]
alignb 16
resw 256
end_app:

then your start code becomes

mov sp,end_app
mov bx,sp
shr bx,4

First of all, let me thank you for suggesting NASM.
That piece of advice was really *golden* 😃

I have not used the [section .bss], so I will be diving into that, but did something similar in some of my other code.

mov	bx,end+100h
shr bx,4
inc bx
mov sp,bx
shl sp,4

But when I started out, optimizations and dynamic complexity really confused me.
Static memory size was just something I copied from the original code, keeping it simple.

After optimizing later on I was really confused that the addresses were jumping, due to it being dynamic and me changing the code when programming.
Of course that had everything to do with me:

  • not using the code segments from the child process
  • not saving registers when I needed to
  • not using the stack properly

Good times! 😆

Reply 42 of 44, by secmaster

User metadata
Rank Newbie
Rank
Newbie

I am doing the similar loader as what Akuma did
However, my problem is that the executable I am working will sometime go to protected mode and
it will use dos extender to write the memory into address greater than 1Mb
I built the loader with nasm and running in real mode (16bit) add modified the interrupt 21h to add my own code (i.e. changed the int vector of 21)
I can see from dosbox debugger that my code is running, but it is in real mode, all the memory content I want to check from the executable is gone (as it is marked in protected mode)
Please can you shed some light how can i access the memory in real mode? Or i need to switch to protected mode? (it seems very complicated for newbie like me)
p.s. the memory address I want to check is at 0x0044a30c

DosIssue.png
BITS    16
;memsize equ 220h ;memory size 220h/544 bytes
;org 0x7c00 ;this is a .com file
org 0x100
section .data
message db 'my loader.',0Dh,0Ah,
db '2021',0Dh,0Ah,'$'
filename db 'SSDFLASH.EXE',0 ;filename to load
params times 22 db 000h ;parameter block is 22 bytes
; see int21h=4b documentation
HEX_OUT db '00000000',0dh,0ah, 0

section .text
;------------------------------------------------------------------------------
start:
;------------------------------------------------------------------------------
;we reposition the stackpointer memsize,
; set no. pages in bx by dividing: memsize / pagesize (16 bytes) = no. pages
; then we resize our memory usage to the number of pages

mov sp, end_app
mov bx,sp
shr bx,4
; mov sp,memsize ;point stackpointer
; to end of memory
; mov bx,memsize/010h ;no. pages = memsize / 16
mov ah,04Ah ;resize memory
int 21h ;commit

mov dx,message ;point to message
mov ah,009h ;write string to stdout
int 21h ;commit

;------------------------------------------------------------------------------
;keystroke function uses a lot of stack space and could overwrite the end
; of your program in memory if memsize is set too small

; mov ah,000h ;keyboard - get keystroke
; int 16h ;commit

;------------------------------------------------------------------------------
;the interrupt vector table contains addresses and we retrieve the address
; from interrupt 16h and save it into the jump address oldint
; do not forget to restore es, because we need it later

mov ah,035h ;get interrupt vector
mov al,21h ;for interrupt 16h
int 21h ;commit
;retuns es:bx=segment:offset
mov word [oldint+1],bx ;write offset to oldint
mov word [oldint+3],es ;write segment to oldint
push cs ;copy cs
pop es ;into es (restores es)

mov ah,025h ;set new interrupt vector
mov al,21h ;for interrupt 016h
mov dx,newint ;ds:dx = new address
int 21h ;commit

;------------------------------------------------------------------------------
Show last 185 lines
;we set the filename (ds:dx) and parameters (es:bx) and then copy
; our own cs segment into the parameter block

mov dx,filename ;filename to load
mov bx,params ;parameter block (es:bx)
mov word [bx+00],cs ;code segment
mov word [bx+02],080h ;command tail offset
mov word [bx+04],cs ;code segment
mov word [bx+06],05Ch ;first FCB
mov word [bx+08],cs ;code segment
mov word [bx+10],06Ch ;second FCB
mov word [bx+12],cs ;code segment
mov ah,04Bh ;exec - load and/or execute
mov al,000h ;load and execute
int 21h ;commit
push ax ;save return code

;------------------------------------------------------------------------------
;we restore the 16h interrupt (ds:dx) from the old address in oldint

mov ah,025h ;set new interrupt vector
mov al,21h ;for interrupt 016h
mov dx,word [oldint+1] ;copy offset from oldint
mov ds,word [oldint+3] ;copy segment from oldint
int 21h ;commit
push cs ;copy cs
pop ds ;into ds (restores ds)

pop ax ;restore exec return code
mov ah,04Ch ;exit to dos
int 21h

;------------------------------------------------------------------------------
;this is our new interrupt 16h function we point to which jumps to the
; old interrupt afterwards. all registers that change must be saved and
; restored afterwards to allow normal execution of the old interrupt.
; in our case its only the flags.

newint:

pushf ;save flags
pusha
cmp ah, 03eh
jnz exit

mov edx, 0x0044a30c
cmp word [edx], 0ec89h
jnz exit

mov edx, ebp
;mov edx, ebp
call print_hex
mov ax,0e20h ;point to message

int 10h
mov ax,0e48h ;point to message

int 10h
mov ax,0e65h ;point to message

int 10h
mov ax,0e6ch ;point to message

int 10h
mov ax,0e6ch ;point to message

int 10h
mov ax,0e6fh ;point to message

int 10h
mov ax,0e21h ;point to message

int 10h
mov ax,0e0dh ;point to message

int 10h
mov ax,0e0ah ;point to message

int 10h
mov ax, 0e0dh
int 10h
mov ax, 0e0ah
;mov dl, 02h
int 10h

exit:
popa
popf ;restore flags
oldint:
jmp 0:0 ;jump to offset:segment
; and set on runtime
;------------------------------------------------------------------------------

print_hex:
; push all registers onto the stack
pusha

; use si to keep track of the current char in our template string mov si, HEX_OUT + 2
mov esi, HEX_OUT

; start a counter of how many nibbles we've processed, stop at 4
mov cx, 0

next_character:
; increment the counter for each nibble
inc cx

; isolate this nibble
mov ebx, edx
and ebx, 0xf0000000
shr ebx, 20

; add 0x30 to get the ASCII digit value
add bh, 0x30

; If our hex digit was > 9, it'll be > 0x39, so add 7 to get
; ASCII letters
cmp bh, 0x39
jg add_7

add_character_hex:
; put the current nibble into our string template
mov [esi], bh

; increment our template string's char position
inc esi

; shift dx by 4 to start on the next nibble (to the right)
shl edx, 4

; exit if we've processed all 4 nibbles, else process the next
; nibble
cmp cx, 8
jnz next_character
and bh, 0
mov [esi], bh
jmp _done

_done:
; copy the current nibble's ASCII value to a char in our template
; string

mov bx, HEX_OUT

; print our template string
call print_string

; pop all arguments
popa

; return from subroutine
ret

add_7:
; add 7 to our current nibble's ASCII value, in order to get letters
add bh, 0x7

; add the current nibble's ASCII
jmp add_character_hex

print_string:
pusha
mov ah, 0xe

print_character:
mov al, [bx]
inc bx
or al, al
jz print_done
int 0x10
jmp print_character

print_done:
popa
ret





section .bss
alignb 16
resw 256
end_app:

Reply 43 of 44, by Akuma

User metadata
Rank Member
Rank
Member

This is beyond me, however there must be process that swaps the memory around. My first bet is to figure out what that is and hook into that.

Reply 44 of 44, by secmaster

User metadata
Rank Newbie
Rank
Newbie
Akuma wrote on 2021-09-10, 14:53:

This is beyond me, however there must be process that swaps the memory around. My first bet is to figure out what that is and hook into that.

Thanks Akuma, i tried to use unreal mode, but without luck.
Not sure what else can do