News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

Run-Time Dynamic Linking Example

Started by Vortex, October 10, 2024, 05:59:42 AM

Previous topic - Next topic

Vortex

This example does not import any function from system DLLs and it uses the run-time dynamic linking method to call API functions :

.386
.model flat,stdcall
option casemap:none

include PEBstruct.inc

MB_OK equ 0

GetProcAddr PROTO :DWORD,:DWORD

.data

LoadLibrary db 'LoadLibraryA',0
MessageBox  db 'MessageBoxA',0
ExitProcess db 'ExitProcess',0
user32      db 'user32.dll',0
msg         db 'Hello from MessageBox',0

.code

start:

    call    main

    push    0
    call    eax                 ; Call ExitProcess

main PROC uses esi ebx

    mov     ebx,[fs:030h]       ;   PEB
    mov     ebx,[ebx+00Ch]      ;   PEB->Ldr
    mov     ebx,[ebx+014h]      ;   PEB->Ldr.InMemoryOrderModuleList.Flink (1st entry)
    mov     ebx,[ebx]           ;   2nd Entry
    mov     ebx,[ebx]           ;   3rd Entry
    mov     ebx,[ebx+010h]      ;   Third entry's base address (Kernel32.dll)

    invoke  GetProcAddr,ebx,ADDR LoadLibrary

    push    OFFSET user32
    call    eax

    invoke  GetProcAddr,eax,ADDR MessageBox

    push    MB_OK
    push    OFFSET user32
    push    OFFSET msg
    push    0
    call    eax                 ; Call MessageBox

    invoke  GetProcAddr,ebx,ADDR ExitProcess

    ret

main ENDP

END start

ognil

Thank you Vortex,

64 bit -> get address of K.E.R.N.E.L.3.2...D.L.L.
    mov     rax,GS:[60h]            ; PEB
    mov     rax,[rax+18h]           ; PEB->Ldr
    mov     rax,[rax+10h]           ; PEB->Ldr.InMemoryOrderModuleList.Flink (1st entry)
    mov     rax,[rax]               ; 1st Entry
    mov     rax,[rax]               ;
    mov     rax,[rax+60h]           ; 2nd Entry K.E.R.N.E.L.3.2..D.L.L
:thumbsup:
"Not keeping emotions under control is another type of mental distortion."

NoCforMe

[ahem] Would you mind explaining to someone, like me, who's totally unfamiliar with the use of this register in assembly language (and what it points to), just what this does?

    mov    ebx,[fs:030h]      ;  PEB

Looks like everything else is chained from this value.

BTW, what's the point of all this? Is this for people who, for some reason, hate include files?
Assembly language programming should be fun. That's why I do it.

jj2007

Quote from: NoCforMe on October 10, 2024, 04:47:14 PMmov    ebx,[fs:030h]      ;  PEB

This is what hackers use to get access to the kernel.

Vortex

#4
Hi NoCforMe,

Someone in Pelle's forum asked about the possibility of an executable not importing from kernel32.dll  My example is only for educational purpose.

The TEB \ Thread Environment Block address can be retrieved from the FS register. FS:0x30 points to the PEB \ Process Environment Block structure :

typedef struct _TEB {
  PVOID Reserved1[12];
  PPEB  ProcessEnvironmentBlock;
  PVOID Reserved2[399];
  BYTE  Reserved3[1952];
  PVOID TlsSlots[64];
  BYTE  Reserved4[8];
  PVOID Reserved5[26];
  PVOID ReservedForOle;
  PVOID Reserved6[4];
  PVOID TlsExpansionSlots;
} TEB, *PTEB;

4*12=48 = 0x30 -> FS:0x30

https://en.wikipedia.org/wiki/Win32_Thread_Information_Block

NoCforMe

Cool, I guess.

Reminds me of the good old DOS days. I remember using undocumented INT 21 function 62H, which returned a pointer to the currently-executing PSP (program segment prefix), which might be a program other than yours, allowing you do to all kinds of crazy things.

Thanks but no thanks. I'll stick to the boring old documented stuff.

Quote from: Vortex on October 11, 2024, 05:31:30 AMhttps://en.wikipedia.org/wiki/Win32_Thread_Information_Block

Y'know, you can make an actual clickable link out of that like this. It's right there in the post editor. People ought to make use of it.
Assembly language programming should be fun. That's why I do it.

sinsi

Quote from: Vortex on October 11, 2024, 05:31:30 AMSomeone in Pelle's forum asked about the possibility of an executable not importing from kernel32.dll
I would imagine that such an EXE would send your anti-virus into a frenzy :biggrin:

NoCforMe

Quote from: Vortex on October 11, 2024, 05:31:30 AMSomeone in Pelle's forum asked about the possibility of an executable not importing from kernel32.dll  My example is only for educational purpose.

So what, exactly, are we supposed to learn from this?
Assembly language programming should be fun. That's why I do it.

HSE

Fantastic Vortex  :thumbsup:

Just yesterday I was reading that from PEB a program can know if is running inside a debugger  :biggrin:
Equations in Assembly: SmplMath

Vortex

Hi NoCforMe,

QuoteSo what, exactly, are we supposed to learn from this?

The utility of the Process Environment Block :

PEB STRUCT                                                    ; sizeof = 0210h
    InheritedAddressSpace               BYTE         ?        ; 0000h
    ReadImageFileExecOptions            BYTE         ?        ; 0001h
    BeingDebugged                       BYTE         ?        ; 0002h
    SpareBool                           BYTE         ?        ; 0003h
    Mutant                              DWORD        ?        ; 0004h
    ImageBaseAddress                    DWORD        ?        ; 0008h
    Ldr                                 DWORD        ?        ; 000Ch PTR PEB_LDR_DATA
    ProcessParameters                   DWORD        ?        ; 0010h PTR RTL_USER_PROCESS_PARAMETERS
    SubSystemData                       DWORD        ?        ; 0014h
    ProcessHeap                         DWORD        ?        ; 0018h
    FastPebLock                         DWORD        ?        ; 001Ch PTR RTL_CRITICAL_SECTION
    FastPebLockRoutine                  DWORD        ?        ; 0020h
    FastPebUnlockRoutine                DWORD        ?        ; 0024h
    EnvironmentUpdateCount              DWORD        ?        ; 0028h
    KernelCallbackTable                 DWORD        ?        ; 002Ch
    SystemReserved                      DWORD    1 dup(?)     ; 0030h
    PebBits                             PEB_BITS    <>        ; 0034h named by Four-F
    FreeList                            DWORD        ?        ; 0038h PTR PEB_FREE_BLOCK
    TlsExpansionCounter                 DWORD        ?        ; 003Ch
    TlsBitmap                           DWORD        ?        ; 0040h
    TlsBitmapBits                       DWORD    2 dup(?)     ; 0044h
    ReadOnlySharedMemoryBase            DWORD        ?        ; 004Ch
    ReadOnlySharedMemoryHeap            DWORD        ?        ; 0050h
    ReadOnlyStaticServerData            DWORD        ?        ; 0054h
    AnsiCodePageData                    DWORD        ?        ; 0058h
    OemCodePageData                     DWORD        ?        ; 005Ch
    UnicodeCaseTableData                DWORD        ?        ; 0060h
    NumberOfProcessors                  DWORD        ?        ; 0064h
    NtGlobalFlag                        DWORD        ?        ; 0068h
                                        DWORD        ?        ; 0064h padding
    CriticalSectionTimeout              LARGE_INTEGER <>      ; 0070h
    HeapSegmentReserve                  DWORD        ?        ; 0078h
    HeapSegmentCommit                   DWORD        ?        ; 007Ch
    HeapDeCommitTotalFreeThreshold      DWORD        ?        ; 0080h
    HeapDeCommitFreeBlockThreshold      DWORD        ?        ; 0084h
    NumberOfHeaps                       DWORD        ?        ; 0088h
    MaximumNumberOfHeaps                DWORD        ?        ; 008Ch
    ProcessHeaps                        DWORD        ?        ; 0090h
    GdiSharedHandleTable                DWORD        ?        ; 0094h
    ProcessStarterHelper                DWORD        ?        ; 0098h
    GdiDCAttributeList                  DWORD        ?        ; 009Ch
    LoaderLock                          DWORD        ?        ; 00A0h
    OSMajorVersion                      DWORD        ?        ; 00A4h
    OSMinorVersion                      DWORD        ?        ; 00A8h
    OSBuildNumber                       WORD         ?        ; 00ACh
    OSCSDVersion                        WORD         ?        ; 00AEh
    OSPlatformId                        DWORD        ?        ; 00B0h
    ImageSubsystem                      DWORD        ?        ; 00B4h
    ImageSubsystemMajorVersion          DWORD        ?        ; 00B8h
    ImageSubsystemMinorVersion          DWORD        ?        ; 00BCh
    ImageProcessAffinityMask            DWORD        ?        ; 00C0h
    GdiHandleBuffer                     DWORD       34 dup(?) ; 00C4h
    PostProcessInitRoutine              DWORD        ?        ; 014Ch
    TlsExpansionBitmap                  DWORD        ?        ; 0150h
    TlsExpansionBitmapBits              DWORD       32 dup(?) ; 0154h
    SessionId                           DWORD        ?        ; 01D4h
    AppCompatFlags                      LARGE_INTEGER <>      ; 01D8h
    AppCompatFlagsUser                  LARGE_INTEGER <>      ; 01E0h
    pShimData                           DWORD        ?        ; 01E8h
    AppCompatInfo                       DWORD        ?        ; 01ECh
    CSDVersion                          UNICODE_STRING <>     ; 01F0h
    ActivationContextData               DWORD        ?        ; 01F8h
    ProcessAssemblyStorageMap           DWORD        ?        ; 01FCh
    SystemDefaultActivationContextData  DWORD        ?        ; 0200h
    SystemAssemblyStorageMap            DWORD        ?        ; 0204h
    MinimumStackCommit                  DWORD        ?        ; 0208h
                                        DWORD        ?        ; 020Ch padding
PEB ENDS

These fields are providing valuable information :

    OSMajorVersion                      DWORD        ?
    OSMinorVersion                      DWORD        ?
    OSBuildNumber                       WORD         ?

sinsi

KERNEL32 uses it all the time, e.g.
GetProcessHeap:
    mov  eax,[fs:30h]
    mov  eax,[eax+18h]
    ret