Exetools

Exetools (https://forum.exetools.com/index.php)
-   General Discussion (https://forum.exetools.com/forumdisplay.php?f=2)
-   -   [HELP] How to write a simple Loader in ASM on MSDOS (https://forum.exetools.com/showthread.php?t=21166)

stoney81 12-07-2024 03:19

[HELP] How to write a simple Loader in ASM on MSDOS
 
Hi guys!

I´m having trouble protecting a DOS Exe (with Overlay) and none of the tools in the otherwise excellent DOSEXE Collection seems to work, so I thought why not try to learn something along the way.

I would need a simple Loader (best would be ASM Code I could compile with nasm) that would load a XORed or otherwise encrypted game.bin File. The idea is to encrypt the Overlay EXE and use the Loader to load the file. This way no one can just snoop around in the EXE.

Protection doesn´t have to be bullet proof, it should just fend off newbies who try to hexedit or check for changes.

Any ideas or resources I could study?

Thank You!

- stoney

ZeNiX 12-18-2024 16:15

Are you sure you are going to write a protector for 8-bit/16-bit MS-DOS Exe files?

sendersu 12-18-2024 20:19

Even in 202x there are COBOL/Fortran/etc engineers that earn 1K per day :)

chants 12-19-2024 03:52

Just to clarify DOS was a 16 bit OS, based on 8 bit CPM. As for overlays there is a nice explanation of some of the details here: https://retrocomputing.stackexchange.com/a/25742 so you will need to know more than just the relevant MZ header fields as the interrupts and segmentation and all these things must be done correctly. In general overlays which are generally for limited memory systems are not needed in a modern context if you can recompile the original DOS program without them. It was designed in days RAM was scarce. That's why they don't exist in PE applications

BlackWhite 12-19-2024 23:15

Quote:

Originally Posted by chants (Post 132345)
Just to clarify DOS was a 16 bit OS, based on 8 bit CPM. As for overlays there is a nice explanation of some of the details here: https://retrocomputing.stackexchange.com/a/25742 so you will need to know more than just the relevant MZ header fields as the interrupts and segmentation and all these things must be done correctly. In general overlays which are generally for limited memory systems are not needed in a modern context if you can recompile the original DOS program without them. It was designed in days RAM was scarce. That's why they don't exist in PE applications

PE may also have an overlay which for example is actually a DLL

BlackWhite 12-20-2024 15:55

Quote:

Originally Posted by stoney81 (Post 132282)
Hi guys!

I´m having trouble protecting a DOS Exe (with Overlay) and none of the tools in the otherwise excellent DOSEXE Collection seems to work, so I thought why not try to learn something along the way.

I would need a simple Loader (best would be ASM Code I could compile with nasm) that would load a XORed or otherwise encrypted game.bin File. The idea is to encrypt the Overlay EXE and use the Loader to load the file. This way no one can just snoop around in the EXE.

Protection doesn´t have to be bullet proof, it should just fend off newbies who try to hexedit or check for changes.

Any ideas or resources I could study?

Thank You!

- stoney



I write the following code ad lib which should meet your needs.
Pls note, after compiling the code and get an exe say ovl.exe,
you should use a hex editor to append at least one byte say 0xCB i.e. retf at the end of ovl.exe

Code:

comment #
Demo for Loading an Overlay in 16-bit Assembly Language
                          Written by [email protected]
                          Dec 20, 2024
#
.386
code segment use16
assume cs:code, ds:code
;input:
;  [bp+4] = PSP's segment address
;  [bp+6] = self_name's offset address
;  [bp+8] = self_name's segment address
;output:
;  [bp+8]:[bp+6] -> self_name
get_self_name proc
  push bp
  mov bp, sp
  push ds
  push es
  push si
  push di
  mov es, [bp+4]  ; ES = PSP's segment address
  mov es, es:[2Ch] ; The environment block's segment address resides at PSP:[2Ch]
                        ; ES:0->environment block which contains the running program's name
        mov  cx, 7FFFh
        mov  di, 0
        mov  al, 0
        cld
scan_it:
        repnz scasb
        cmp byte ptr es:[di], 0
        je  catch_it
        loop scan_it
catch_it:
        push es
        pop  ds
        mov si, di
        add si, 3
  les di, [bp+6]; ES:DI->self_name
copy_name:       
  lodsb
        or al, al
        jz  catch_end
        stosb
        jmp copy_name
catch_end:
        stosb
  pop di
  pop si
        pop es
        pop ds
  pop bp
  ret
get_self_name endp


;input:
;  [bp+4]->file_name
;  [bp+6]->handle
;output:
;  EAX = file_len
;  *[bp+6] = handle
;  CF = 1 for error
;  CF = 0 for success
get_self_size proc
  push bp
  mov bp, sp
  push bx
  mov ax, 3D00h
  mov dx, [bp+4]
  int 21h
  mov bx, [bp+6]
  mov [bx], ax
  jc get_self_size_done
  mov bx, ax
  mov ax, 4202h
  xor cx, cx
  xor dx, dx
  int 21h
  shl edx, 10h
  mov dx, ax
  mov eax, edx
  push eax
  mov ax, 4200h
  xor cx, cx
  xor dx, dx
  int 21h
  pop eax
  clc
get_self_size_done:
  pop bx
  pop bp
  ret
get_self_size endp

;input:
;  [bp+4] = handle
;output:
;  EAX = head_and_image_size
get_head_and_image_size proc
  push bp
  mov bp, sp
  sub sp, 6
  push bx
  push ds
  mov ah, 3Fh
  mov bx, [bp+4]
  mov cx, 6
  lea dx, [bp-6]
  push ss
  pop ds
  int 21h
  movzx eax, word ptr [bp-2]
  shl eax, 9
  mov dx, word ptr [bp-4]
  sub dx, 200h
  neg dx
  and dx, 1FFh
  movzx edx, dx
  sub eax, edx
  pop ds
  pop bx
  mov sp, bp
  pop bp
  ret
get_head_and_image_size endp

psp        dw 0
handle    dw 0
self_name  db 40h dup(0)
self_size  dd 0
head_and_image_size dd 0
overlay_size dd 0
overlay_entry dw 0
overlay_seg  dw 0
main:
  mov cs:[psp], ds
  push cs
  pop ds
  ;
  push cs
  mov ax, offset self_name
  push ax
  push [psp]
  call get_self_name
  add sp, 6
  ;
  ;
  mov ax, offset handle
  push ax
  mov ax, offset self_name
  push ax
  call get_self_size
  pop cx
  pop cx
  mov [self_size], eax
  jnc continue
  jmp done
  ;
continue:
  push [handle]
  call get_head_and_image_size
  add sp, 2
  mov [head_and_image_size], eax
  ;
  mov eax, [self_size]
  sub eax, [head_and_image_size]
  mov [overlay_size], eax
  ;
  mov bx, offset end_flag
  add bx, 100h+0Fh
  shr bx, 4
  push es
  mov ah, 4Ah
  mov es, [psp]
  int 21h; reallocate memory
  pop es
  ;
  mov ah, 48h
  mov bx, word ptr [overlay_size]
  add bx, 0Fh
  shr bx, 4
  int 21h
  mov [overlay_seg], ax
  ;
  mov ax, 4200h
  mov bx, [handle]
  mov ecx, [head_and_image_size]
  mov dx, cx
  shr ecx, 10h
  int 21h; fseek
  ;
  push ds
  mov ah, 3Fh
  mov bx, [handle]
  mov cx, word ptr [overlay_size]
  xor dx, dx
  mov ds, [overlay_seg]
  int 21h; read overlay
  mov ah, 3Eh
  int 21h; close file
  pop ds
  ;
  push ds
  push es
  mov cx, word ptr [overlay_size]
  mov es, [overlay_seg]
  mov ds, [overlay_seg]
  xor si, si
  xor di, di
decode_overlay:
  lodsb
  ; xor al, 42h; put your decoding algorithm here
  stosb
  loop decode_overlay
  pop es
  pop ds
  ;
  call dword ptr [overlay_entry]
  ;
  push es
  mov ah, 49h
  mov es, [overlay_seg]
  int 21h; free memory
  pop es
  ;
done:
  mov ah, 4Ch
  int 21h
end_flag label byte
code ends
end main



All times are GMT +8. The time now is 22:16.

Powered by vBulletin® Version 3.8.8
Copyright ©2000 - 2026, vBulletin Solutions, Inc.
Always Your Best Friend: Aaron, JMI, ahmadmansoor, ZeNiX