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
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:
[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?
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.
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 (https://en.wikipedia.org/wiki/Win32_Thread_Information_Block)
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 (https://en.wikipedia.org/wiki/Win32_Thread_Information_Block). It's right there in the post editor. People ought to make use of it.
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:
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?
Fantastic Vortex :thumbsup:
Just yesterday I was reading that from PEB a program can know if is running inside a debugger :biggrin:
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 ?
KERNEL32 uses it all the time, e.g.
GetProcessHeap:
mov eax,[fs:30h]
mov eax,[eax+18h]
ret