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
Filename
DosIssue.png
File size
101.31 KiB
Views
652 views
File license
Public domain
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 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