PDA

View Full Version : deprotecting memory of a dll image


BanMe
February 11th, 2011, 12:40
I want to just overwrite a string in ntdll and it gets all bitchy at me..So I decided to smack it with a mallet, so to speak..This has a issue with NtProtectVirtualMemory currently but all is due in time..
seh.inc fille 'hmm I fixed it for you..'?
updated code..
Code:

.486
.model flat,stdcall
option casemap:none
code SEGMENT DWORD flat PUBLIC 'text'
Scstart:
assume fs:nothing
push 006c006fh ;- 8
mov esi,dword ptr fs:[30h]
add esi,20h;RtlEnterCriticalSection
lodsd
and eax,0ffff0000h;get ntdll's base;clear off the extra
mov esi,[eax+170h];read reloc offset from PE
mov ebx,[eax+174h];read reloc size from PE
push eax ;- 4
add esi,eax
next_section:
lodsd
mov edx,eax
lodsd
sub ebx,eax
sub eax,8h
mov ecx,eax
find_data:
lodsw
and eax,0fffh
pop edi ;get base address
add eax,edi
add eax,edx
push edi
push esi
test eax,edi
jl next_entry
mov esi, dword ptr [eax]
cmp esi,edi;that shoud fix it Indy??
jl next_entry
mov edi,dword ptr [esp+8h]
cmp dword ptr [esi],edi
je NtProtect_Module
next_entry:
pop esi
sub ecx,2
cmp ecx,2
jne find_data
add esi,2
jmp next_section
end_this:
mov eax,1
ret
NtProtect_Module:
mov edx,[esp+4h]
push esi
mov edi,edx
mov ecx,[edx+14ch]
add edx,[edx+148h]
add edx,ecx
mov esi,edx
xor eax,eax
find_NtProtect:
lodsw
cmp eax,089b8h
jne find_NtProtect
sub esi,2
push ebp
push esp
sub esp,10h
mov dword ptr [esp],-1
mov dword ptr [ebp],edi
mov dword ptr [esp+4],ebp
mov dword ptr [ebp+4],0b2000h
add ebp,4
mov dword ptr [esp+8h],ebp
mov dword ptr [esp+0Ch],4h
add ebp,4
xor eax,eax
mov dword ptr [ebp],eax
mov [esp+10h],ebp
call esi
test eax,eax
jnz end_this
mov edi,[esp+4h]
pop esp
pop ebp
write_string:
push 00730077h
pop eax
stosd
push 005f0032h
pop eax
stosd
push 00320033h
pop eax
stosd
push 0064002eh
pop eax
stosd
push 006C006Ch
pop eax
stosd
ret
end Scstart
code ENDS


regards BanMe



Quote:

NX SEH (promotion chain sec outside the modules).
In the UM set flazhek MEM_EXECUTE_OPTION_EXECUTE_DISPATCH_ENABLE not succeed because of the established flag
MEM_EXECUTE_OPTION_PERMANENT. In KM, these options are not used. Possible ways:
o Load system module without its initialization and zeroing directory exclusions and table handler
s in the configuration directory of the module. Code is placed in the data section of this module and installed atm
ribut E for the section (region).
o Promotion sec hand. In the UM through VEH. In KM by KD (puts severe restrictions) bagcheko
in (private) or any other suitable mechanism. This requires the use of a graph to check the occurrence
of Ip in the protected code described by the graph.
o Dynamic copying procedures in place within the module. Also requires the rebuilding of the graph for an
arbitrary implementation of the protected code.
o The UM Trace Manager exceptions VEH before entering the service NtQueryInformationProcess (ProcessExecu
teFlags) and Checking MEM_EXECUTE_OPTION_EXECUTE_DISPATCH_ENABLE.

Indy
February 12th, 2011, 04:11
Entry from the blog:
Quote:
NX SEH(раскрутка цепочки сех вне модулей.
В UM установить флажёк MEM_EXECUTE_OPTION_EXECUTE_DISPATCH_ENABLE не удастся изза установленного флажка
MEM_EXECUTE_OPTION_PERMANENT. В KM эти опции не используются. Возможные способы:
o Загрузка системного модуля без его инициализации и обнулением директории исключений и таблицы хэндлер
ов в директории конфигурации модуля. Код помещается в секцию данных этого модуля и устанавливается ат
рибут E для секции(региона.
o Раскрутка сех вручную. В UM посредством VEH. В KM посредством KD(ставит жёсткие ограничения, багчеко
в(приват или любого иного подходящего механизма. Это требует использование графа для проверки вхожде
ния Ip в защищаемый код описываемый графом.
o Динамическое копирование процедур в место в пределах модуля. Также требует пересборку графа для произ
вольной реализации защищаемого кода.
o В UM трассировка диспетчера исключений в VEH до входа в сервис NtQueryInformationProcess(ProcessExecu
teFlags) и установка флажка MEM_EXECUTE_OPTION_EXECUTE_DISPATCH_ENABLE.

Then I reviewed the stack protection(Stpt). This allows to place SEH anywhere. Otherwise SEH is not called.

BanMe
February 12th, 2011, 10:42
What of other options?
like for instance..
PEB linking and loading a internally crafted PE 'dll' and setting that 'module' to MEM_EXECUTE_OPTION_IMAGE_DISPATCH_ENABLE..and activate the ldr accordingly?

Indy
February 12th, 2011, 11:29
BanMe
Your decision not to allow you to find an optimum between hiding and flexibility. Outside modules handler will not be called.)

BanMe
February 12th, 2011, 16:40


http://blogs.msdn.com/b/junfeng/archive/2004/04/28/121871.aspx

The "ExecuteOptions" key..hmm..interesting to find that..and and then reality warp..
Code:

if (CurrentProcess->Pcb.Flags.ExecuteEnable != 0) {
CurrentProcess->Pcb.Flags.ExecuteDispatchEnable = 1;
CurrentProcess->Pcb.Flags.ImageDispatchEnable = 1;
}

names..
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\shellcode.dll and as above..

Indy testing and researching is my goal what happens along the way is anyone's guess..

Indy
February 13th, 2011, 14:41
BanMe
Crash your code:
Code:
mov esi, dword ptr [eax] ;read the data located..

Eax = 0x7D205A51.
*MZ + 0x170 refers to exception directory. Need to read the offset PE-header.

BanMe
February 13th, 2011, 15:28
what version of windows are you using o0? maybe I neglected to mention this is XP sp3 x86 specific..

Code:

$+160 > 00000000 DD 00000000 ; Exception Table address = 0
$+164 > 00000000 DD 00000000 ; Exception Table size = 0
$+168 > 00000000 DD 00000000 ; Certificate File pointer = 0
$+16C > 00000000 DD 00000000 ; Certificate Table size = 0
$+170 > 00F00A00 DD 000AF000 ; Relocation Table address = AF000
$+174 > E02E0000 DD 00002EE0 ; Relocation Table size = 2EE0 (12000.)

Indy
February 13th, 2011, 16:30
2427

BanMe
February 13th, 2011, 22:02
242824292430

Your suggestion for improvement is noted..

your on professional.. and my laptop is home edition..So to make it work on both you suggest a modification as such..

From this:
Code:

and eax,0ffff0000h;get ntdll's base;clear off the extra
mov esi,[eax+170h];read reloc offset from PE
mov ebx,[eax+174h];read reloc size from PE


To this:
Code:

and eax,0ffff0000h;get ntdll's base;clear off the extra
mov ecx,eax
add ecx, dword [eax+3ch]
mov eax,[ecx+0a0h];read reloc offset from PE
mov ebx,[ecx+0a4h];read reloc size from PE


Thanks

Indy
February 13th, 2011, 23:38
Yes, but this does not solve the problem of SEH. Its use does not make sense if the code is not described in the loader. And shellcode usually does not contain zeros..

BanMe
February 14th, 2011, 00:35
SEH in the above was just a tool to see the 'data' available on stack when exception occurs, the SEH will fail, NtprotectVirtualMemory fails and try to
stosd again causing the same error at same location of stack and 'protection'..

real shell code below but prolly not up to snuff yet..its a 'learning creation'?

Indy
February 14th, 2011, 09:11
Same crash. In my worth to describe the problem, not the evil hacks )

BanMe
February 14th, 2011, 13:50
Code:

00401000 > 33FF XOR EDI,EDI ; ntdll.7C910228
00401002 8BD7 MOV EDX,EDI ; ntdll.7C910228
00401004 EB 22 JMP SHORT minimali.00401028
00401006 F1 INT1
00401007 FFFF ??? ; Unknown command
00401009 FFF2 PUSH EDX ; ntdll.KiFastSystemCallRet
0040100B FFFF ??? ; Unknown command
0040100D FFF3 PUSH EBX
0040100F FFFF ??? ; Unknown command
00401011 FFF1 PUSH ECX
00401013 FFFF ??? ; Unknown command
00401015 FFF2 PUSH EDX ; ntdll.KiFastSystemCallRet
00401017 FFFF ??? ; Unknown command
00401019 FFF3 PUSH EBX
0040101B FFFF ??? ; Unknown command
0040101D FF5E 56 CALL FAR FWORD PTR DS:[ESI+56]
00401020 C3 RETN
00401021 47 INC EDI ; ntdll.7C910228
00401022 8BC7 MOV EAX,EDI ; ntdll.7C910228
00401024 8BE2 MOV ESP,EDX ; ntdll.KiFastSystemCallRet
00401026 0F34 SYSENTER
00401028 E8 F1FFFFFF CALL minimali.0040101E
0040102D 66:83FF 18 CMP DI,18
00401031 74 17 JE SHORT minimali.0040104A
00401033 8BC2 MOV EAX,EDX ; ntdll.KiFastSystemCallRet
00401035 3C 14 CMP AL,14
00401037 74 14 JE SHORT minimali.0040104D
00401039 8BD6 MOV EDX,ESI
0040103B 83EA 14 SUB EDX,14
0040103E 83EE 29 SUB ESI,29
00401041 8932 MOV DWORD PTR DS:[EDX],ESI
00401043 8962 FC MOV DWORD PTR DS:[EDX-4],ESP
00401046 8BF2 MOV ESI,EDX ; ntdll.KiFastSystemCallRet
00401048 ^EB D7 JMP SHORT minimali.00401021
0040104A 47 INC EDI ; ntdll.7C910228
0040104B ^EB E0 JMP SHORT minimali.0040102D
0040104D 33ED XOR EBP,EBP
0040104F 8BFD MOV EDI,EBP
00401051 8BF5 MOV ESI,EBP
00401053 8BCD MOV ECX,EBP
00401055 83C1 1C ADD ECX,1C
00401058 83E9 14 SUB ECX,14
0040105B 64:3329 XOR EBP,DWORD PTR FS:[ECX]
0040105E 89242F MOV DWORD PTR DS:[EDI+EBP],ESP
00401061 66:23D7 AND DX,DI
00401064 8955 18 MOV DWORD PTR SS:[EBP+18],EDX ; ntdll.KiFastSystemCallRet
00401067 83C5 18 ADD EBP,18
0040106A 8BE5 MOV ESP,EBP
0040106C 68 6FFF6CFF PUSH FF6CFF6F
00401071 33F6 XOR ESI,ESI
00401073 8BDE MOV EBX,ESI
00401075 46 INC ESI
00401076 F61434 NOT BYTE PTR SS:[ESP+ESI]
00401079 46 INC ESI
0040107A 46 INC ESI
0040107B F61434 NOT BYTE PTR SS:[ESP+ESI]
0040107E 46 INC ESI
0040107F 33C9 XOR ECX,ECX
00401081 83C1 3C ADD ECX,3C
00401084 331411 XOR EDX,DWORD PTR DS:[ECX+EDX]
00401087 83C1 3C ADD ECX,3C
0040108A 83C1 2C ADD ECX,2C
0040108D 335C0A FC XOR EBX,DWORD PTR DS:[EDX+ECX-4]
00401091 33D3 XOR EDX,EBX
00401093 32D2 XOR DL,DL
00401095 83ED FC SUB EBP,-4
00401098 8BF2 MOV ESI,EDX ; ntdll.KiFastSystemCallRet
0040109A 8BFD MOV EDI,EBP
0040109C A5 MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ES>
0040109D A5 MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ES>
0040109E 83C7 FC ADD EDI,-4
004010A1 8307 F8 ADD DWORD PTR DS:[EDI],-8
004010A4 8B0F MOV ECX,DWORD PTR DS:[EDI]
004010A6 33DB XOR EBX,EBX
004010A8 66:A5 MOVS WORD PTR ES:[EDI],WORD PTR DS:[ESI]
004010AA 83C1 FE ADD ECX,-2
004010AD 3BCB CMP ECX,EBX
004010AF 74 31 JE SHORT minimali.004010E2
004010B1 66:4B DEC BX
004010B3 43 INC EBX
004010B4 43 INC EBX
004010B5 83EB 11 SUB EBX,11
004010B8 66:C1C3 1C ROL BX,1C
004010BC 215F FE AND DWORD PTR DS:[EDI-2],EBX
004010BF 2BD2 SUB EDX,EDX ; ntdll.KiFastSystemCallRet
004010C1 3355 FC XOR EDX,DWORD PTR SS:[EBP-4]
004010C4 3357 FA XOR EDX,DWORD PTR DS:[EDI-6]
004010C7 3357 FE XOR EDX,DWORD PTR DS:[EDI-2]
004010CA 3B55 FC CMP EDX,DWORD PTR SS:[EBP-4]
004010CD 7C 0E JL SHORT minimali.004010DD
004010CF 8B12 MOV EDX,DWORD PTR DS:[EDX]
004010D1 3B55 FC CMP EDX,DWORD PTR SS:[EBP-4]
004010D4 7C 07 JL SHORT minimali.004010DD
004010D6 8B5D F8 MOV EBX,DWORD PTR SS:[EBP-8] ; kernel32.7C817080
004010D9 391A CMP DWORD PTR DS:[EDX],EBX
004010DB 74 07 JE SHORT minimali.004010E4
004010DD 83C7 FE ADD EDI,-2
004010E0 ^75 C4 JNZ SHORT minimali.004010A6
004010E2 ^EB B6 JMP SHORT minimali.0040109A
004010E4 8BDA MOV EBX,EDX ; ntdll.KiFastSystemCallRet
004010E6 8B5424 04 MOV EDX,DWORD PTR SS:[ESP+4] ; ntdll.7C910228
004010EA 8B8A 4C010000 MOV ECX,DWORD PTR DS:[EDX+14C]
004010F0 0392 48010000 ADD EDX,DWORD PTR DS:[EDX+148]
004010F6 03D1 ADD EDX,ECX
004010F8 8BF2 MOV ESI,EDX ; ntdll.KiFastSystemCallRet
004010FA 33C0 XOR EAX,EAX
004010FC 66:AD LODS WORD PTR DS:[ESI]
004010FE 66:3D B889 CMP AX,89B8
00401102 ^75 F8 JNZ SHORT minimali.004010FC
00401104 83EE 02 SUB ESI,2
00401107 83EC 14 SUB ESP,14
0040110A C70424 FFFFFFFF MOV DWORD PTR SS:[ESP],-1
00401111 8B7C24 04 MOV EDI,DWORD PTR SS:[ESP+4] ; ntdll.7C910228
00401115 83C5 FC ADD EBP,-4
00401118 896C24 04 MOV DWORD PTR SS:[ESP+4],EBP
0040111C C745 04 00200B00 MOV DWORD PTR SS:[EBP+4],0B2000
00401123 83C5 04 ADD EBP,4
00401126 896C24 08 MOV DWORD PTR SS:[ESP+8],EBP
0040112A C74424 0C 040000>MOV DWORD PTR SS:[ESP+C],4
00401132 83C5 04 ADD EBP,4
00401135 33C0 XOR EAX,EAX
00401137 8945 00 MOV DWORD PTR SS:[EBP],EAX
0040113A 896C24 10 MOV DWORD PTR SS:[ESP+10],EBP
0040113E FFD6 CALL ESI
00401140 85C0 TEST EAX,EAX
00401142 75 25 JNZ SHORT minimali.00401169
00401144 8BFB MOV EDI,EBX
00401146 68 77007300 PUSH 730077
0040114B 58 POP EAX ; kernel32.7C817077
0040114C AB STOS DWORD PTR ES:[EDI]
0040114D 68 32005F00 PUSH 5F0032
00401152 58 POP EAX ; kernel32.7C817077
00401153 AB STOS DWORD PTR ES:[EDI]
00401154 68 33003200 PUSH 320033
00401159 58 POP EAX ; kernel32.7C817077
0040115A AB STOS DWORD PTR ES:[EDI]
0040115B 68 2E006400 PUSH 64002E
00401160 58 POP EAX ; kernel32.7C817077
00401161 AB STOS DWORD PTR ES:[EDI]
00401162 68 6C006C00 PUSH 6C006C
00401167 58 POP EAX ; kernel32.7C817077
00401168 AB STOS DWORD PTR ES:[EDI]
00401169 C3 RETN
its getting easier as I practice and more fun to document with math

Indy
February 16th, 2011, 19:00
Code:
.code
SIGNATURE_LENGTH equ 44H

Ip proc

; LdrpFixSectionProtection:
; ...
; 6A FF push -1
; E8 XXXXXXXX call ntdll.ZwProtectVirtualMemory
; [LINE]
; 68 XXXXXXXX ; ASCII "Set 0x%X protection for %p section for %d bytes, old protection 0x%X",LF
; [LINE]
; E8 XXXXXXXX call ntdll.DbgPrintEx

Local BaseOfCode:PVOID, SizeOfCode:PVOID
assume fs:nothing
mov eax,fs:[TEB.Peb]
mov eax,PEB.Ldr[eax]
mov eax,PEB_LDR_DATA.InLoadOrderModuleList.Flink[eax]
mov eax,LDR_DATA_TABLE_ENTRY.InLoadOrderModuleList.Flink[eax]
mov ebx,LDR_DATA_TABLE_ENTRY.DllBase[eax] ; ntdll.dll
mov ecx,ebx
add ecx,IMAGE_DOS_HEADER.e_lfanew[ecx]
assume ecx:PIMAGE_NT_HEADERS
mov esi,[ecx].OptionalHeader.BaseOfCode
mov edi,[ecx].OptionalHeader.SizeOfCode
lea esi,[esi + ebx - 4]
cld
mov SizeOfCode,edi
mov BaseOfCode,esi
sub edi,SIGNATURE_LENGTH
Step:
mov ecx,SIGNATURE_LENGTH/4
xor eax,eax
@@:
xor eax,dword ptr [esi + ecx*4]
xor eax,ecx
rol eax,cl
loop @b
cmp eax,60EC54DCH ; Hash
je Found
inc esi
dec edi
jnz Step
int 3
Found:
mov ecx,SizeOfCode
lea eax,[esi + 4]
mov edx,BaseOfCode
sub ecx,24H
Scan:
cmp dword ptr [ecx + edx + 24H],eax
je @f
loop Scan
int 3
@@:
lea esi,[ecx + edx + 23H]
cmp byte ptr [esi],68H
jne Scan
sub esi,20H
mov ecx,20H
@@:
cmp word ptr [esi + ecx],0FF6AH
je Vale
loop @b
int 3
Vale:
cmp byte ptr [esi + ecx + 2],0E8H
jne @b
lea eax,[esi + ecx + 7]
add eax,dword ptr [eax - 4] ; *ZwProtectVirtualMemory

; push service arg's.
; Call Eax

.if byte ptr [eax] != 0B8H
int 3
.endif

mov eax,dword ptr [eax + 1] ; ID

.if Eax > 1000H
int 3
.endif

; push service arg's.
; mov edx,esp
; Int 2EH
; add esp,5*4

Ip endp
end Ip
2434

BanMe
February 17th, 2011, 22:14
LOL it toook me a bit to understand the 'construct' idea...the continuation of a idea I had for find cross platform signatures amazing..o0

Your view may are to malware oriented my friend, lighten up and 'play' more(you already started to?) :P

commented to show my ideas..

1.shell coding is limited in by numerous thing 1 of which is access to numbers..
2.the next issue is not having the ldr know anything about the code unless it's in a PE, with regards to relocs.
Code:

xor ebx,ebx;0 ebx
jmp OverData;...
dd 021365719h
dd 0fffffff4h
dd 0fffffff8h
dd 0fffffffch
dd 0fffffff1h
Data_endings:
pop esi
push esi
ret
OverData:
call Data_endings;get return address
mov edi,esp;store esp
sub esi,01ch;get data begginings
mov esp,esi;move to stack
pop edx;read data 21365719h
sub esp,esi;esp = 4
sub esi,esp;esi = entry point
xor ebx,esp;ebx + 4
mov esp,edi;restore esp
rollitup:
mov ecx,14h
rol edx,cl
dec ebx
dec ebx
jnz rollitup;roll the data
xor edi,edi
xor edi,dword ptr [esi+14h];read fffffff1
dec edi;fffffff0
not edi;0000000f;
and ecx,edi;ecx = 4
and edx,edi;edx = 1
add esi,04ch
push esi
ret;return to ret +1
self locating code is can be turned to 'self' relocating code and gives me grounds to explore more..other fun things in the code as well..But only to those that can 'see' the ideas.

after execution of this code with ebx = 0;
EAX ;remains as is..
ECX ;4
EDX ;1
EBX ;0
ESP ;remains as is
EBP ;remains as is
ESI ;entry of this routine
EDI 0000000F
[48]signature

This really does nothing it was just a prototype of thought..

Indy
February 17th, 2011, 23:18
BanMe
Code:
10001001 33DB XOR EBX,EBX
10001003 EB 17 JMP SHORT 1000101C
10001005 1957 36 SBB DWORD PTR DS:[EDI+36],EDX
10001008 21F4 AND ESP,ESI
1000100A FFFF ??? ; Unknown command
...

What is it ??

Not acceptable to find stub:
Quote:
find_NtProtect:
lodsw
cmp eax,089b8h
jne find_NtProtect

ZwGetCurrentProcessorNumber in W7, ZwExtendSection in Vista etc.

BanMe
February 19th, 2011, 15:53
Further fun with 'that'..off by 1 'sysenter' the question then becomes how does yours 'fit' 'that'?

for all those people 'possibly' reading this.. o0 this code executes totally position independent and executes with ret to 'stack' style programming .
the instructions executed on the stack are

Code:

mov edx,esp
sysenter
ret


also being that I have a tendency to code dll's this returned me to the oh so fun place I erred at before o0..
the code executed by such was:

Code:

7C90118A |. 8BE6 MOV ESP,ESI
7C90118C |. 5B POP EBX
7C90118D |. 5F POP EDI
7C90118E |. 5E POP ESI
7C90118F |. 5D POP EBP
7C901190 \. C2 1000 RETN 10


and I had poisoned esi....
you might recognize EIP ?
Code:

EAX C000001C
ECX 00000001
EDX FFFFFFFF
EBX FFFFFFF1
ESP 10001027
EBP FFFFFFFC
ESI FFFFFFC3
EDI 340FD48B
EIP FFFFFFF1


Code:

int 3
jmp OverData
dw 0fff1h
dw 0ffffh
dw 01f34h
dw 0d48bh
dd 0ffffffc3h
dd 0fffffffch
dd 0fffffff1h
Data_endings:
pop esi
push esi
ret
OverData:
call Data_endings
xor ecx,ecx
mov ebx,ecx
mov edi,esp
sub esi,01ch
mov esp,esi
pop edx
dec edx
pop cx
rol cx,cl
dec cx
rol cx,14h
pop bx
push cx
push bx
mov ecx,esp
mov esp,edi
push ecx
ret


Your question might have been 'what could it be'?

I thought your solution was very good, but you leave no room for improvement...

I havent seen updated engine, but I am now looking forward to it more then ever.

Indy
February 19th, 2011, 20:15
Bind sysenter/ret does not make sense. Return of service executed on instruction [0x7FFE0304(map on kernel as 0xFFDF0304)] = ntdll!KiFastSystemCallRet, except for the first service pack XP(there is a return to the map).
That manager:
Code:
_KiFastCallEntry proc

;
; Sanitize the segment registers
;
mov ecx, KGDT_R3_DATA OR RPL_MASK
push KGDT_R0_PCR
pop fs
mov ds, ecx
mov es, ecx

;
; When we trap into the kernel via fast system call we start on the DPC stack. We need
; shift to the threads stack before enabling interrupts.
;
mov ecx, PCR[PcTss] ;
mov esp, [ecx]+TssEsp0

push KGDT_R3_DATA OR RPL_MASK ; Push user SS
push edx ; Push ESP
pushfd
Kfsc10:
push 2 ; Sanitize eflags, clear direction, NT etc
add edx, 8 ; (edx) -> arguments
popfd ;
.errnz(EFLAGS_INTERRUPT_MASK AND 0FFFF00FFh)
or byte ptr [esp+1], EFLAGS_INTERRUPT_MASK/0100h ; Enable interrupts in eflags

push KGDT_R3_CODE OR RPL_MASK ; Push user CS
push dword ptr ds:[USER_SHARED_DATA+UsSystemCallReturn] ; push return address
...

Eax: Service ID
Edx: *Arg's - 2*4(on the bottom of the stack is a reference to Ret, so calling a Call).

Better use of Int 0x2e.

BanMe
February 21st, 2011, 10:41
It was 'really' hard to come up with a 'test' that 'shows' the information given..But much was learned in the 'trying'..if its not already been done..locating a function by error codes(commented out of code to show Indy's 'line' better.)
Code:

.486
.model flat,stdcall
option casemap:none
code SEGMENT DWORD flat PUBLIC 'text'
Scstart:
int 3
xor edi,edi
jmp OverData
dd 0fffffff1h,0fffffff2h,0fffffff3h,0fffffff4h
dd 0fffffff5h,0fffffff6h,0fffffff7h,0fffffff8h
dd 0fffffff9h,0fffffffah,0fffffffbh,0fffffffch
dd 0fffffffdh,0fffffffeh,0ffffffffh,0ffffff1fh
dd 0ffffff11h,0ffffff12h,0ffffff13h,0ffffff14h
dd 0ffffff15h,0ffffff16h,0ffffff17h,0ffffff18h
dd 0ffffff19h,0ffffff1ah,0ffffff1bh
Data_endings:
pop esi
push esi
ret
int_Enter:
push int_Enter
inc edi
mov eax,edi
mov edx,esi
dw 340fh
OverData:
call Data_endings
;test if I found NtAllocateVirtualMemory
;cmp al, 0f3h ~c00000f3h
mov edx,esi
sub edx,14h
sub esi,7fh
dec esi
mov ecx,esi
add ecx,-2
mov dword ptr [esi],ecx
mov dword ptr[esi+4],esp
add esi,28h
mov esp,esi
pushad
sub esi, 28h
mov esp,edx
pushad
jmp int_Enter
end Scstart
code ENDS


The error that shows what you speak happens in NtClose.. I guess passing in pseudo random information is bad...it shows it in a very obscure way..my entry point is overwritten.. with ntdll!KiFastSystemCallRet..

To explain my 'test' it simply loops 'sysenter' and 'fudges' a stack into itself..from 0 upward it returns error codes.. for me it hits 'your point' at eax = 19h. I see what you say when I must code non dependent to the ldr providing 'me' information...

Indy
February 22nd, 2011, 00:47
You can not do it, can get to NtShutdownSystem(need some rights) and other dangerous services.

BanMe
February 22nd, 2011, 02:35
This is not what I am afraid of...
Code:

int 3
xor edi,edi
mov edx,edi
jmp OverData
dd 0fffffff1h,0fffffff2h,0fffffff3h
dd 0fffffff1h,0fffffff2h,0fffffff3h
Data_endings:
pop esi
push esi
ret
Sys_Enter:
inc edi
mov eax,edi
mov esp,edx
dw 340fh
OverData:
call Data_endings
;Test if I am 1 before NtClose on XP and if I found KiFastSystemCallRet
Stack_travel:
cmp di,18h
je inc_edi
mov eax,edx
cmp al,14h
je found_nt_dll
mov edx,esi
sub edx,14h
sub esi,29h
mov dword ptr [edx],esi
mov dword ptr[edx-4],esp
mov esi,edx
jmp Sys_Enter
inc_edi:
inc edi
jmp Stack_travel
found_nt_dll:
assume fs:nothing
xor ebp,ebp
mov edi,ebp

Indy
February 22nd, 2011, 10:15
Code:
push 0
push 0
;...
mov ebx,1000H - 1
@@:
mov eax,ebx
mov edx,esp
Int 2EH
dec ebx
jnz @b


BanMe
February 22nd, 2011, 11:55
yes but for the 'single steppers' out there... this 'will' loop sysenter.. bp xor ebp,ebp and f9..at 0..

Could I get the 'code' leading up to the first relocation for Vista and 7 in ntdll just x86 "please"..

the code with the 'least amount' of relocation seems to hold the more interesting 'areas'.

Code:

7C901000 > $ 64:8B0D 18000000 MOV ECX,DWORD PTR FS:[18]
7C901007 . 8B5424 04 MOV EDX,DWORD PTR SS:[ESP+4]
7C90100B . 837A 14 00 CMP DWORD PTR DS:[EDX+14],0
7C90100F . 75 4F JNZ SHORT ntdll.7C901060
7C901011 > F0:FF42 04 LOCK INC DWORD PTR DS:[EDX+4] ; LOCK prefix
7C901015 . 75 19 JNZ SHORT ntdll.7C901030
7C901017 > 8B41 24 MOV EAX,DWORD PTR DS:[ECX+24]
7C90101A . 8942 0C MOV DWORD PTR DS:[EDX+C],EAX
7C90101D . C742 08 01000000 MOV DWORD PTR DS:[EDX+8],1
7C901024 . 33C0 XOR EAX,EAX
7C901026 . C2 0400 RETN 4
7C901029 . 8DA424 00000000 LEA ESP,DWORD PTR SS:[ESP]
7C901030 > 8B41 24 MOV EAX,DWORD PTR DS:[ECX+24]
7C901033 . 3942 0C CMP DWORD PTR DS:[EDX+C],EAX
7C901036 . 75 08 JNZ SHORT ntdll.7C901040
7C901038 . FF42 08 INC DWORD PTR DS:[EDX+8]
7C90103B . 33C0 XOR EAX,EAX
7C90103D . C2 0400 RETN 4
7C901040 > 52 PUSH EDX
7C901041 . E8 518A0100 CALL ntdll.RtlpWaitForCriticalSection
7C901046 . 64:8B0D 18000000 MOV ECX,DWORD PTR FS:[18]
7C90104D . 8B5424 04 MOV EDX,DWORD PTR SS:[ESP+4]
7C901051 .^EB C4 JMP SHORT ntdll.7C901017
7C901053 . 8DA424 00000000 LEA ESP,DWORD PTR SS:[ESP]
7C90105A . 8D9B 00000000 LEA EBX,DWORD PTR DS:[EBX]
7C901060 > 8B41 24 MOV EAX,DWORD PTR DS:[ECX+24]
7C901063 . 3942 0C CMP DWORD PTR DS:[EDX+C],EAX
7C901066 . 75 18 JNZ SHORT ntdll.7C901080
7C901068 . F0:FF42 04 LOCK INC DWORD PTR DS:[EDX+4] ; LOCK prefix
7C90106C . FF42 08 INC DWORD PTR DS:[EDX+8]
7C90106F . 33C0 XOR EAX,EAX
7C901071 . C2 0400 RETN 4
7C901074 . 8DA424 00000000 LEA ESP,DWORD PTR SS:[ESP]
7C90107B . 05 00000000 ADD EAX,0
7C901080 > FF72 14 PUSH DWORD PTR DS:[EDX+14]
7C901083 > B8 FFFFFFFF MOV EAX,-1
7C901088 . B9 00000000 MOV ECX,0
7C90108D . F0:0FB14A 04 LOCK CMPXCHG DWORD PTR DS:[EDX+4],ECX ; LOCK prefix
7C901092 . 75 1C JNZ SHORT ntdll.7C9010B0
7C901094 . 83C4 04 ADD ESP,4
7C901097 . 64:8B0D 18000000 MOV ECX,DWORD PTR FS:[18]
7C90109E . 8B41 24 MOV EAX,DWORD PTR DS:[ECX+24]
7C9010A1 . 8942 0C MOV DWORD PTR DS:[EDX+C],EAX
7C9010A4 . C742 08 01000000 MOV DWORD PTR DS:[EDX+8],1
7C9010AB . 33C0 XOR EAX,EAX
7C9010AD . C2 0400 RETN 4
7C9010B0 > 837A 04 01 CMP DWORD PTR DS:[EDX+4],1
7C9010B4 . 7D 0D JGE SHORT ntdll.7C9010C3
7C9010B6 > F3: PREFIX REP: ; Superfluous prefix
7C9010B7 . 90 NOP
7C9010B8 . 837A 04 FF CMP DWORD PTR DS:[EDX+4],-1
7C9010BC .^74 C5 JE SHORT ntdll.7C901083
7C9010BE . FF0C24 DEC DWORD PTR SS:[ESP]
7C9010C1 .^75 F3 JNZ SHORT ntdll.7C9010B6
7C9010C3 > 83C4 04 ADD ESP,4
7C9010C6 . 64:8B0D 18000000 MOV ECX,DWORD PTR FS:[18]
7C9010CD .^E9 3FFFFFFF JMP ntdll.7C901011
7C9010D2 8D DB 8D
7C9010D3 A4 DB A4
7C9010D4 24 DB 24 ; CHAR '$'
7C9010D5 00 DB 00
7C9010D6 00 DB 00
7C9010D7 00 DB 00
7C9010D8 00 DB 00
7C9010D9 8D DB 8D
7C9010DA A4 DB A4
7C9010DB 24 DB 24 ; CHAR '$'
7C9010DC 00 DB 00
7C9010DD 00 DB 00
7C9010DE 00 DB 00
7C9010DF 00 DB 00
7C9010E0 > $ 8B5424 04 MOV EDX,DWORD PTR SS:[ESP+4]
7C9010E4 . 33C0 XOR EAX,EAX
7C9010E6 . FF4A 08 DEC DWORD PTR DS:[EDX+8]
7C9010E9 . 75 25 JNZ SHORT ntdll.7C901110
7C9010EB . 8942 0C MOV DWORD PTR DS:[EDX+C],EAX
7C9010EE . F0:FF4A 04 LOCK DEC DWORD PTR DS:[EDX+4] ; LOCK prefix
7C9010F2 . 7D 03 JGE SHORT ntdll.7C9010F7
7C9010F4 . C2 0400 RETN 4
7C9010F7 > 52 PUSH EDX
7C9010F8 . E8 628A0100 CALL ntdll.RtlpUnWaitCriticalSection
7C9010FD . 33C0 XOR EAX,EAX
7C9010FF . C2 0400 RETN 4
7C901102 . 8DA424 00000000 LEA ESP,DWORD PTR SS:[ESP]
7C901109 . 8DA424 00000000 LEA ESP,DWORD PTR SS:[ESP]
7C901110 > F0:FF4A 04 LOCK DEC DWORD PTR DS:[EDX+4] ; LOCK prefix
7C901114 . C2 0400 RETN 4
7C901117 90 NOP
7C901118 > $ 8B4C24 04 MOV ECX,DWORD PTR SS:[ESP+4]
7C90111C . B8 FFFFFFFF MOV EAX,-1
7C901121 . BA 00000000 MOV EDX,0
7C901126 . F0:0FB151 04 LOCK CMPXCHG DWORD PTR DS:[ECX+4],EDX ; LOCK prefix
7C90112B . 75 18 JNZ SHORT ntdll.7C901145
7C90112D . 64:A1 24000000 MOV EAX,DWORD PTR FS:[24]
7C901133 . 8941 0C MOV DWORD PTR DS:[ECX+C],EAX
7C901136 . C741 08 01000000 MOV DWORD PTR DS:[ECX+8],1
7C90113D . B8 01000000 MOV EAX,1
7C901142 . C2 0400 RETN 4
7C901145 > 64:A1 24000000 MOV EAX,DWORD PTR FS:[24]
7C90114B . 3941 0C CMP DWORD PTR DS:[ECX+C],EAX
7C90114E . 74 07 JE SHORT ntdll.7C901157
7C901150 . 33C0 XOR EAX,EAX
7C901152 . F3: PREFIX REP: ; Superfluous prefix
7C901153 . 90 NOP
7C901154 . C2 0400 RETN 4
7C901157 > F0:FF41 04 LOCK INC DWORD PTR DS:[ECX+4] ; LOCK prefix
7C90115B . FF41 08 INC DWORD PTR DS:[ECX+8]
7C90115E . B8 01000000 MOV EAX,1
7C901163 . C2 0400 RETN 4
7C901166 > $ 8D4424 10 LEA EAX,DWORD PTR SS:[ESP+10]
7C90116A . 894424 04 MOV DWORD PTR SS:[ESP+4],EAX
7C90116E . 33ED XOR EBP,EBP
7C901170 . E9 DA870100 JMP ntdll.LdrpInitialize
7C901175 90 NOP
7C901176 >/$ 55 PUSH EBP
7C901177 |. 8BEC MOV EBP,ESP
7C901179 |. 56 PUSH ESI
7C90117A |. 57 PUSH EDI
7C90117B |. 53 PUSH EBX
7C90117C |. 8BF4 MOV ESI,ESP
7C90117E |. FF75 14 PUSH DWORD PTR SS:[EBP+14]
7C901181 |. FF75 10 PUSH DWORD PTR SS:[EBP+10]
7C901184 |. FF75 0C PUSH DWORD PTR SS:[EBP+C]
7C901187 |. FF55 08 CALL DWORD PTR SS:[EBP+8]
7C90118A |. 8BE6 MOV ESP,ESI
7C90118C |. 5B POP EBX
7C90118D |. 5F POP EDI
7C90118E |. 5E POP ESI
7C90118F |. 5D POP EBP
7C901190 \. C2 1000 RETN 10
7C901193 90 NOP
7C901194 90 NOP
7C901195 90 NOP
7C901196 90 NOP
7C901197 90 NOP
7C901198 > $ 8BFF MOV EDI,EDI
7C90119A . 55 PUSH EBP
7C90119B . 8BEC MOV EBP,ESP
7C90119D . 56 PUSH ESI
7C90119E . 57 PUSH EDI
7C90119F . 64:A1 18000000 MOV EAX,DWORD PTR FS:[18]
7C9011A5 . 8BB0 B0010000 MOV ESI,DWORD PTR DS:[EAX+1B0]
7C9011AB . 85F6 TEST ESI,ESI
7C9011AD . 8B7D 0C MOV EDI,DWORD PTR SS:[EBP+C]
7C9011B0 . 0F85 1DED0000 JNZ ntdll.7C90FED3
7C9011B6 . 85FF TEST EDI,EDI
7C9011B8 . 0F85 1EED0000 JNZ ntdll.7C90FEDC
7C9011BE > 803D 94E0977C 00 CMP BYTE PTR DS:[RtlpNotAllowingMultipleActivation],0

Code:

CPU Disasm
Address Hex dump Command Comments
77A41000 /> /3BF0 CMP ESI,EAX
77A41002 |. |0F85 83F30700 JNE 77AC038B
77A41008 |> |0FB645 08 MOVZX EAX,BYTE PTR SS:[EBP+8]
77A4100C |. |6A 04 PUSH 4 ; /Arg4 = 4
77A4100E |. |8945 10 MOV DWORD PTR SS:[EBP+10],EAX ; |
77A41011 |. |8D45 10 LEA EAX,[EBP+10] ; |
77A41014 |. |50 PUSH EAX ; |Arg3
77A41015 |. |6A 1D PUSH 1D ; |Arg2 = 1D
77A41017 |. |6A FF PUSH -1 ; |Arg1 = -1
77A41019 |. |E8 3A7F0500 CALL ZwSetInformationProcess ; \ntdll.ZwSetInformationProcess
77A4101E \. |EB 7B JMP SHORT 77A4109B
77A41020 . |90 NOP
77A41021 . |90 NOP
77A41022 . |90 NOP
77A41023 . |90 NOP
77A41024 . |90 NOP
77A41025 /$ |8BFF MOV EDI,EDI
77A41027 |. |55 PUSH EBP
77A41028 |. |8BEC MOV EBP,ESP
77A4102A |. |56 PUSH ESI
77A4102B |. |8B75 0C MOV ESI,DWORD PTR SS:[ARG.2]
77A4102E |. |33C0 XOR EAX,EAX
77A41030 |. |3BF0 CMP ESI,EAX
77A41032 |. |0F85 6DF30700 JNE 77AC03A5
77A41038 |> |3845 10 CMP BYTE PTR SS:[ARG.3],AL
77A4103B |. |0F85 6BF30700 JNE 77AC03AC
77A41041 |> |3BF0 CMP ESI,EAX
77A41043 |. |0F85 84F30700 JNE 77AC03CD
77A41049 |> |0FB645 08 MOVZX EAX,BYTE PTR SS:[ARG.1]
77A4104D |. |6A 04 PUSH 4 ; /Arg4 = 4
77A4104F |. |8945 10 MOV DWORD PTR SS:[ARG.3],EAX ; |
77A41052 |. |8D45 10 LEA EAX,[ARG.3] ; |
77A41055 |. |50 PUSH EAX ; |Arg3 => OFFSET ARG.3
77A41056 |. |6A 12 PUSH 12 ; |Arg2 = 12
77A41058 |. |6A FE PUSH -2 ; |Arg1 = -2
77A4105A |. |E8 097F0500 CALL NtSetInformationThread ; \ntdll.NtSetInformationThread
77A4105F |> |5E POP ESI
77A41060 |. |5D POP EBP
77A41061 \. |C3 RETN
77A41062 |90 NOP
77A41063 |90 NOP
77A41064 |90 NOP
77A41065 |90 NOP
77A41066 |90 NOP
77A41067 |8BFF MOV EDI,EDI
77A41069 /. |55 PUSH EBP
77A4106A |. |8BEC MOV EBP,ESP
77A4106C |. |56 PUSH ESI
77A4106D |. |8B75 0C MOV ESI,DWORD PTR SS:[ARG.2]
77A41070 |. |33C0 XOR EAX,EAX
77A41072 |. |3BF0 CMP ESI,EAX
77A41074 |. |0F85 0AF30700 JNE 77AC0384
77A4107A |> |3845 10 CMP BYTE PTR SS:[ARG.3],AL
77A4107D |.^\74 81 JE SHORT 77A41000
77A4107F |. |64:8B0D 18000 MOV ECX,DWORD PTR FS:[18]
77A41086 |. |8B49 30 MOV ECX,DWORD PTR DS:[ECX+30]
77A41089 |. |F741 68 00001 TEST DWORD PTR DS:[ECX+68],00100000
77A41090 |.^\0F85 6AFFFFFF JNE 77A41000
77A41096 |. B8 010000C0 MOV EAX,C0000001
77A4109B |> 5E POP ESI
77A4109C |. 5D POP EBP
77A4109D \. C3 RETN
77A4109E 90 NOP
77A4109F 90 NOP
77A410A0 . 90 NOP
77A410A1 . 90 NOP
77A410A2 . 90 NOP
77A410A3 /$ 8BFF MOV EDI,EDI
77A410A5 |. 55 PUSH EBP
77A410A6 |. 8BEC MOV EBP,ESP
77A410A8 |. 51 PUSH ECX
77A410A9 |. 8D45 FC LEA EAX,[LOCAL.1]
77A410AC |. 50 PUSH EAX ; /Arg6 => OFFSET LOCAL.1
77A410AD |. 6A 00 PUSH 0 ; |Arg5 = 0
77A410AF |. 6A 00 PUSH 0 ; |Arg4 = 0
77A410B1 |. 6A 00 PUSH 0 ; |Arg3 = 0
77A410B3 |. 6A 00 PUSH 0 ; |Arg2 = 0
77A410B5 |. 6A 18 PUSH 18 ; |Arg1 = 18
77A410B7 |. E8 CC800500 CALL NtTraceControl ; \ntdll.NtTraceControl
77A410BC |. 85C0 TEST EAX,EAX
77A410BE |. 0F85 CF2D0800 JNE 77AC3E93
77A410C4 |> 50 PUSH EAX ; /Arg1
77A410C5 |. E8 56790300 CALL 77A78A20 ; \ntdll.77A78A20
77A410CA |. C9 LEAVE
77A410CB \. C3 RETN
77A410CC /> A8 01 TEST AL,01
77A410CE |. 0F85 F9620300 JNE 77A773CD
77A410D4 |. EB 08 JMP SHORT 77A410DE
77A410D6 |> 0FB7F7 MOVZX ESI,DI
77A410D9 |. E9 2E630300 JMP 77A7740C
77A410DE |> C745 E4 0D000 MOV DWORD PTR SS:[EBP-1C],C000000D
77A410E5 \. E9 8A630300 JMP 77A77474
77A410EA 90 NOP
77A410EB 90 NOP
77A410EC 90 NOP
77A410ED 90 NOP
77A410EE 90 NOP
77A410EF /$ 8BFF MOV EDI,EDI
77A410F1 |. 55 PUSH EBP
77A410F2 |. 8BEC MOV EBP,ESP
77A410F4 |. 81EC E0000000 SUB ESP,0E0
77A410FA |. A1 C041B077 MOV EAX,DWORD PTR DS:[77B041C0]

Indy
February 23rd, 2011, 17:59
BanMe
If I understand you need a code enumerates the fixups.
Code:
; typedef VOID (*LDR_FIXUP_ENUMERATION_CALLBACK)(
; IN PVOID ImageBase,
; IN PVOID Fixup,
; IN PVOID Context,
; IN OUT BOOLEAN *StopEnumeration
; );
;
xLdrEnumerateFixups proc uses ebx esi edi ImageBase:PVOID, Section:PIMAGE_SECTION_HEADER, Ip:PVOID, CallbackRoutine:PVOID, CallbackParameter:PVOID
Local ExitFlag:BOOLEAN
Local SectionBaseVA:ULONG, SectionLimitVA:ULONG
Call SEH_Epilog_Reference
Call SEH_Prolog
.if ImageBase == NULL
mov eax,fs:[TEB.Peb]
mov ecx,PEB.LoaderLock[eax]
mov eax,PEB.Ldr[eax]
mov eax,PEB_LDR_DATA.InLoadOrderModuleList.Flink[eax]
mov eax,LDR_DATA_TABLE_ENTRY.InLoadOrderModuleList.Flink[eax]
mov eax,LDR_DATA_TABLE_ENTRY.DllBase[eax] ; ntdll.dll
mov ImageBase,eax
.endif
invoke LdrImageNtHeader, ImageBase, addr ExitFlag
test eax,eax
mov ecx,ExitFlag
mov edx,Section
jnz Exit
test edx,edx
mov esi,IMAGE_NT_HEADERS.OptionalHeader.DataDirectory.VirtualAddress[ecx + IMAGE_DIRECTORY_ENTRY_BASERELOC*sizeof(IMAGE_DATA_DIRECTORY)]
mov edi,IMAGE_NT_HEADERS.OptionalHeader.DataDirectory._Size[ecx + IMAGE_DIRECTORY_ENTRY_BASERELOC*sizeof(IMAGE_DATA_DIRECTORY)]
.if !Zero?
mov eax,IMAGE_SECTION_HEADER.VirtualAddress[edx]
mov SectionBaseVA,eax
add eax,IMAGE_SECTION_HEADER.VirtualSize[edx]
mov SectionLimitVA,eax
.endif
test esi,esi
mov edx,Ip
jz Error
test edx,edx
mov ecx,IMAGE_NT_HEADERS.OptionalHeader.SizeOfImage[ecx]
jz @f
sub edx,ImageBase
jbe Error
cmp edx,ecx
jnb Error
@@:
test edi,edi
jz Error
add esi,ImageBase
add edi,esi ; Limit
assume esi:PIMAGE_BASE_RELOCATION
Scan:
mov ebx,[esi].SizeOfBlock
sub ebx,sizeof(IMAGE_BASE_RELOCATION)
jbe Error ; ..
shr ebx,1
cmp Section,NULL
mov eax,[esi].VirtualAddress
jz @f
cmp SectionBaseVA,eax
mov edx,SectionLimitVA
ja Block
cmp SectionLimitVA,eax
jbe Block
@@:
movzx eax,word ptr [esi + ebx*2 + sizeof(IMAGE_BASE_RELOCATION) - 2]
mov edx,eax
and edx,NOT(0FFFH)
and eax,0FFFH
cmp edx,(IMAGE_REL_BASED_HIGHLOW shl 12)
jne Next
add eax,[esi].VirtualAddress
mov ecx,Ip
add eax,ImageBase
.if !Ecx || dword ptr [Eax] == Ecx
lea edx,ExitFlag
mov ExitFlag,FALSE
push edx
push CallbackParameter
push eax
push ImageBase
Call CallbackRoutine
cmp ExitFlag,FALSE
jne Exit
.endif
Next:
dec ebx
jnz @b
Block:
add esi,[esi].SizeOfBlock
cmp esi,edi
jb Scan
xor eax,eax
jmp Exit
SEH_Epilog_Reference:
%GET_CURRENT_GRAPH_ENTRY
Exit:
Call SEH_Epilog
ret
Error:
mov eax,STATUS_UNSUCCESSFUL
jmp Exit
xLdrEnumerateFixups endp


I just do not quite understand you.

BanMe
February 24th, 2011, 18:18
Thank you for that Sample..recently I changed Sysenter to int2eh and gave it a whirl..
where I landed was very 'interesting'...
Code:

7C90E460 > 83C4 04 ADD ESP,4
7C90E463 5A POP EDX
7C90E464 64:A1 18000000 MOV EAX,DWORD PTR FS:[18];teb
7C90E46A 8B40 30 MOV EAX,DWORD PTR DS:[EAX+30];peb
7C90E46D 8B40 2C MOV EAX,DWORD PTR DS:[EAX+2C];kernelcallbacktable
7C90E470 FF1490 CALL DWORD PTR DS:[EAX+EDX*4];00000130h a exception obviously occurred...
7C90E473 33C9 XOR ECX,ECX
7C90E475 33D2 XOR EDX,EDX
7C90E477 CD 2B INT 2B


That is a most interesting entry to a call.. and It would have a very small pattern to exploit..Sadly that was noted back in 2k..

Indy
February 25th, 2011, 00:49
This is KiUserCallbackDispatcher(). Call the first(callback ClientThreadSetup()) shadow(ID = 1XXX) service(NtGdiInit). You need to load and initialize the module User32.dll
Otherwise the vector table is not filled and there will be #AV.

BanMe
March 22nd, 2011, 17:04
Sorry I miss some things Like version checking and not 'adding' things up properly..(thanks for pointing that out..Indy..way back there..).. (duh.. I want you to aspire to be greater then you where in the 'past'. But that is something that the 'herding machine' we've injected ourselves with does not understand. How is that for 'crazy'...

BanMe
April 2nd, 2011, 13:00
This method doesn't use the PEB to find ntdll. Integrated into this is a anti-single step trick. I used the PEB MAJOR_VERSION and SUBVERSION to uniquely identify OS, I also used System call table from metasploit to pinpoint the index of NtClose, even though SysEnter fuzzing in this code is initially protected from 'single stepping', dynamic adaptation and re-usage of code is a overall repeatable thought.I also shortened and redid the fuzz of sysenter: instead of using a fudged stack I used the code here as the stack ensuring more noticeable errors in interesting API's..

Sometimes we prick ourselves, just to see if 'we' are alive..

numerous updates and fixes but w/e
Code:

.486
.model flat,stdcall
option casemap:NONE
option offset:SEGMENT
code SEGMENT DWORD flat PUBLIC 'text'
assume fs:nothing
;include \masm32\include\windows.inc
;include \masm32\include\ntdll.inc
;includelib \masm32\lib\ntdll.lib
ScStart:
ZeroRegisters:;clear all registers
xor edi,edi
mov eax,edi
mov ecx,edi
mov ebx,edi
mov edx,edi
mov esi,edi
mov ebp,edi
mov ebx,esp;store esp in ebx for initialization purposes...this morphs into a ret..
VersionTrap:
sub edi,-30h
xor esi,fs:[edi];read the peb
sub esi,-74h;...
add esi,edi;a4
sub ecx,-6h;vista
lodsb;read byte from esi
cmp al,cl;check for vista
je vista
sub esi,-3h;
xor ecx,ecx
test_version:
cmp ecx,dword ptr [esi];check subversion for 2k/xp/2k3 0.1.2
je VersionLdr
inc ecx;inc version
jmp test_version
vista:
add ecx,-3
jmp VersionLdr
FoundIndex:
mov ebp,eax;store the index for NtClose in Ebp
dec ebp;minus 1 for proper jump over
mov edi,ecx
mov esi,ecx
jmp FuzzStart
VersionLdr:
push 02f1b1918h;ntclose indexs
mov esi,esp;
inc ecx;inc 1 for proper entry loading 1 for 2k 2 for xp 3 for 2k3 4 for vista.. :]
@@:
lodsb;read byte
loopd @b;loop according to ecx value
pop edi;clear stack
jmp FoundIndex
I_NT:;My own personal answer to beating not having a 'ldr' to rely on..
mov eax,ebx;\
db 0e8h;
dd 0fffffffah;/
ret; Skyphers website has alot of information on this.. read up..He also shows a smaller version of 'this sequence of operation'.. (ALL 'credits' to him for talking about 'it'.)
;\
dd 0ffffffffh;ntdll base address
;/
FuzzStart:
jmp OverData
dd 0fffffff1h,0fffffff2h
Data_endings:
pop esi ;pop return address
push esi ;push return address
ret
SysEnter:
inc edi;start at index 1..(skips 0)
mov eax,edi;store index to eax
mov esp,edx;yay!
dw 340fh;sysenter
OverData:
call Data_endings
FuzzSysEnter:
cmp di,bp;check for 'versioned' NtClose Index
je inc_edi;skip it if found
cmp dl,14h;odd check for 'ntdll' .. 'probably' not cross platform
;though I know all above xp support sysenter they probably all don't return a address with 14h as the last element..
;To bypass this I could test for a PE..which takes me 2 steps forward? :X
je found_ntdll
mov edx,esi
sub edx,13h
sub esi,19h
mov dword ptr [edx],esi
mov dword ptr[edx-4],esp
mov esi,edx
jmp SysEnter
inc_edi:
inc edi
jmp FuzzSysEnter
found_ntdll:
mov esp,ebx
Scratch_NT:
call I_NT
mov esi,dword ptr [esp-8h];read the return address of the first call
inc esi;add 1 to get the 'data' address
xor dx,dx;clear lower bits to get ImageBase
mov dword ptr [esi],edx;store imagebase in the data
inc dx;make dx = 1
cmp di,dx;if di is not equal to 1 then you single stepped my sysenter fuzzer upto 1.. ie u f7'd till u hit sysenter..
jne FoundAStepper
xor cl,cl;
mov esi,ecx
FixZeroRegisters:
lodsw
cmp ax,0DC8bh;find mov ebx,esp
jne FixZeroRegisters
dec esi
dec esi
mov word ptr [esi],0c390h;overwrite it with nop ret
call ecx;call ZeroRegisters
call I_NT
mov esi,dword ptr [esp-8h]
inc esi
mov edi,dword ptr [esi];read ntdll imagebase address
mov esi,dword ptr [esp-4h]
add esi,13h
call esi;and diggin begins...
ret
FoundAStepper:
dw 0b0fh
ParseReloc:
mov esi,edi;
xor esi, dword ptr [edi+3ch];add PE offset to imagebase
sub esi,-0a4h;add a4..
mov ebx,dword ptr [esi];read reloc size from PE ebx
sub esi,4
mov esi,dword ptr [esi];add reloc offset to imagebase
add esi,edi
next_section:
lodsd;read offset from imagebase to get proper relocation
mov edx,eax;store in edx
lodsd;read number of relocations for that offset
sub ebx,eax;minus that from total number of relocations
test ebx,ebx;finished parsing relocations?
jz TakeFurtherAction
GoAllTheWay:
sub eax,8h;minus the size of IMAGE_BASE_RELOC structure from total number of relocations for this offset
mov ecx,eax;store the result in the count
find_data:
mov eax,edi;rewrite image base to eax each loop
lodsw;add reloc entry to imagebase
xor ah,030h;remove entry type from entry
add eax,edx;add image offset from base
push eax;store parsed entry onto stack
sub ecx,2;sub size of entry
cmp ecx,2;check if we are 2 away from next section(0000)
jne find_data;loop
add esi,2;fix us up..
jmp next_section;goto next relocation entry
TestForKernel32:;its a 'higher' up address...fix that..
xor dx,dx;clear lower
dec edx;make ffff
xor dx,dx;clear lower
mov edi,edx;edx = kernel32.dll
jmp ParseReloc;parse the relocation table..
TakeFurtherAction:
mov esi,esp
@@:
pop edx
mov edx,[edx];NAME that symbol..by reading it.. logically speaking of course..
cmp edx,edi;test if we find a address that is less then the image base address
jl TestForKernel32
jg @b
ret
code ends
end ScStart


There is a logical error in this code,and better overall structure can be applied to this code. The error is I don't parse the 'last' entries in the last section because I test ebx,ebx just after the sub(easily remedied), The restructuring is the funnest part: it removes unnecessary code from the overall structure and tries to optimize as much as possible(less is better).. Now I have updated the above with where I am at atm..

Also this current incarnation should also parse Kernel32s relocation section to the stack.. very interesting API name tables from so many API's..I am astounded by the ease of exploitability that is in the 'data'.. dll names and api's and they are available because the loader placed the statically linked addresses in the tables..LOL, digging for dll's without api's or the peb..this is

BanMe
April 2nd, 2011, 23:16
in lieu of not being able to test on vista due to a chewing issue.. I decided to take a step further down this road and pursue my remark about 'finding kernel32 in the data of ntdll'..well as it turns out, this is actually very easy once all the pieces are in play.. So if anyone looked at the listing in the above you would see only a few 'named' symbols but the ones I need are RtlpStartThreadFunc RtlpExitThreadFunc..reason being is that first one is a pointer to somewhere in ntdll ifnot kernel32 is loaded, if kernel32 is loaded it points to Kernel32.BaseCreateThreadPoolThread and im guessing (Kernel32.BaseExitThreadPoolThread)...See above post/code for details..reverse 'postings'? o0 Suggestions for improvement will be 'noted' and as quickly as possible adapted to. Anyone?

BanMe
April 5th, 2011, 19:24
XP HOME...kernel32 and ntdll relocation tables parsed...

wbe seems to enjoy this code o0 ..I can't imagine why when the 'target' had already been cracked..

Due to respect for shub and the contributions made by him and associates.. (many repeated thanks..)

"never let the journey rob you of your dreams."(VH1 wisdom ??)

;This Code is written By BanMe() on the way 'out', I no longer want this handle,
;Maybe Something closer 'To:Me'..would suffice...

;I give this to any who would read it and question my thoughts..
;If this is not the case, then you shouldn't read it..

;I have a Twisted story to 'tell', the story is of my own mind and is solely about myself.
;I never had a conscience or a feeling of anxiety until about 8 years ago..when I was confronted with my own mortality.
;I questioned my character, my decisions, and my 'faith in everything'...
;I had no faith in others until I went fishing with a 'believer'..
;and still I doubted and didn't see the reasons to be 'good' content to be easily 'evil'.
;many philosophical questions followed that oddly 'gave me faith'.
;I then gave at least in part of information that I was ashamed to admit to..
;ashamed because I did it for reasons of doubt in myself and insane uniqueness of thought..after this
;I looked back and saw the 'wrongs' that where committed 'for my name',
;and still I had the audacity and stupidity to think that others where idiots or incapable of natural thoughts.
;All I was, was 'consumed' by 'my' faulty thought process.

;Never again will I reflect my failings onto others, and would encourage you to find your failings and see where they
;have lead you.

;Scary are my 'thoughts of giving', when I am myself not the 'epitome of appropriateness'.
; I would 'give of any part of me to help you, and would not expect anything except the opportunity to learn more..
; I would test your limits and then ask you why that is your limit..

Code:

.486
.model flat,stdcall
option casemap:NONE
option offset:SEGMENT
code SEGMENT DWORD flat PUBLIC 'text'
assume fs:nothing
ZeroRegister:;clear all registers
jmp FixFromBelow
ZeroRegisters:;This zero's registers,no information is available.. o0
xor edi,edi;0 edi
mov eax,edi;0 eax
mov ecx,edi;0 ecx
mov ebx,edi;0 ebx
mov edx,edi;0 edx
mov esi,edi;0 esi
mov edi,edi;hot patch
NotAPE:
xor edx,edx;
mov edi,edi;hot patch..
IfIsAPE:
cmp word ptr [edx],05a4dh;test for ZM
jne NotAPE;jump not equal
mov edi,edi;hot patch
FixFromAbove:
mov ecx,[esp];return address to ecx
GetEntry:
dec cx;ensure proper location by
xor cl,cl;clear of the lower bit
cmp word ptr [ecx],048ebh;test for my eb 48
jne GetEntry;didn't find it, go back further...
mov esi,ecx;found it...
mov edi,edi
Fixup:
cmp esi,[esp]
jg @f
lodsw ;\
dec esi ;\
cmp ax,0ff8bh;find mov edi,edi
jne Fixup ;/
mov word ptr [esi-1],0c390h;overwrite it with nop ret
cmp esi,[esp]
jl Fixup
@@:
mov edi,edi
FixFromBelow:
call FixFromAbove
call ZeroRegisters
jmp FireItUp
VersionTrap:
sub ecx,-4h
sub dh,-3
ror dx,cl
xor esi,fs:[edx];read the peb o0
sub esi,-74h
add esi,edx
inc ecx
inc ecx
lodsb;read byte from esi
cmp al,cl;check for vista
je vista
sub esi,-3h
xor ecx,ecx
test_version:
cmp ecx,dword ptr [esi];check subversion for 2k
je VersionLdr
inc ecx;inc version
jmp test_version
vista:
add ecx,-3
VersionLdr:
inc ecx;inc 1 for proper entry loading
pop edx
mov esi,esp
@@:
lodsb;read byte
loopd @b;loop according to ecx value
FoundIndex:
push edx
ret
FireItUp:
mov ebx,esp
push 02f1b1918h;ntclose indexs
call VersionTrap
mov ebp,eax;store the index for NtClose in Ebp
dec ebp;minus 1 for proper jump over
mov esi,ecx;cleanup
mov edx,ecx;cleanup
jmp OverData
I_NT:;My own personal answer to beating not having a 'ldr' to rely on..
mov eax,ebx
db 0e8h
dd 0fffffffah
ret
;\
dd 0ffffffffh;ntdll base address
;/
dd 0fffffff1h,0fffffff2h
Data_endings:
pop esi
push esi
ret
SysEnter:
inc edi
mov eax,edi
mov esp,edx
dw 340fh
OverData:
call Data_endings
FuzzSysEnter:
test edx,edx;bp here.. :] f9
js FuzzIt
jz FuzzIt
xor dx,dx;ntdll
call IfIsAPE
test edx,edx
jnz found_dll
inc_edi:
inc edi
jmp FuzzSysEnter
FuzzIt:
cmp edi,ebp
je inc_edi
mov edx,esi
sub edx,13h
add esi,-5h
mov dword ptr [edx],esi
mov dword ptr[edx-4],esp
mov esi,edx
jmp SysEnter
found_dll:
call I_NT
mov esi,dword ptr [esp-8h];read the return address of the first call
inc esi;add 1 to get the 'data' address
mov dword ptr [esi],edx;store imagebase in code
xor cl,cl;get my base addess
mov dword ptr [esp-8h],ecx
mov esp,ebx
ParseReloc:
mov edi,edx
mov esi,edx;
xor esi, dword ptr [edx+3ch];add PE offset to imagebase
sub esi,-0a4h;add a4..
mov ebx,dword ptr [esi];read reloc size from PE ebx
add esi,-4h
add edx,dword ptr [esi];add reloc offset to imagebase
mov esi,edx
next_section:
test ebx,ebx;finished parsing relocations?
jz TakeFurtherAction
lodsd;read offset from imagebase to get proper relocation
mov edx,eax;store in edx
lodsd;read number of relocations for that offset
sub ebx,eax;minus that from total number of relocations
sub eax,8h;minus the size of IMAGE_BASE_RELOC structure from total number of relocations for this offset
mov ecx,eax;store the result in the count
xor bp,bp;0
sub bp,-3h;00000003
rol bp,-4h;00003000
find_data:
mov eax,edi;rewrite image base to eax each loop
lodsw;add reloc entry to imagebase
xor ax,bp;remove entry type from entry
add eax,edx;add image offset from base
push eax;store parsed entry onto stack
dec ecx
dec ecx
cmp ecx,2;check if we are 2 away from next section(0000)
jne find_data;loop
inc esi
inc esi
jmp next_section;goto next relocation entry
TakeFurtherAction:
mov ebx,esp
@@:
pop edx
mov edx,[edx];NAME that symbol..by reading it.. logically speaking of course..
cmp edx,edi;test if we find a address that is less then the image base address
jg @b
xor dx,dx;clear lower
dec edx;make ffff
test edx,edx
js OutOfThisLoop
xor dx,dx;clear lower
mov edi,edx;edx = kernel32.dll
mov esp,ebx;dont overwrite entries
call ParseReloc;parse the relocation table..
OutOfThisLoop:
mov esp,ebx
call ZeroRegisters
mov esi,[esp]
dec edx
xor dx,dx
ror edx,-4
xor dx,dx
and esi,edx
mov edi,esi
sub edi,-03ch
mov di,word ptr [edi]
sub edi,-0d8h
xor si,word ptr [edi]
mov edi,esi
PilferTable:
lodsd
push eax
cmp eax,ecx
jne PilferTable
ZeroItOut:
xor edx,edx
mov ebp,edx
sub ebp,-4
TestInterModularCall:
xor eax,eax
lodsd
add eax,esi;ethenol for your mind,and absinthe for the soul..
cmp eax,edi
jl ByteScan
mov edx,edi
xor dx,dx
sub edx, -03ch
mov dx,word ptr [edx]
add edx,dword ptr [edx+50h]
xor dl,dl
dec dx
cmp eax,edx
jg ByteScan
push esi
mov esi,eax
lodsw
cmp ax,0ff8bh;mov edi,edi
jne @f
lodsb
cmp al,055h;push ebp
jne @f
lodsw
cmp ax,0ec8bh;mov ebp,esp
jne @f
lodsb
cmp al,056h;push esi
jne @f
lodsw
cmp ax,0358bh;mov esi,&ntdll.ZwProtectVirtualMemory..
jne @f
lodsd;breakpoint here!
@@:
pop esi
ByteScan:
lodsb
cmp al,0e8h
je TestInterModularCall
jmp ByteScan
IFailz:
ret
code ends
end ZeroRegister
'Im slowly eliminating 0's all of them o0' and re-factoring variants..'

so this will parse ntdll's and kernel32 relocation table.. to the stack of the executing thread that has the delight of executing this function..to prevent it from trying to parse ffff0000 as a PE and error one could then location the LdrGetInLoadOrderModuleList or w/e.. and parse relocs..IAT 'parsing' is my next step..In theory we should be able to factorize this out to a real 'data' to code xref tool.. and find 'data' to not disasm into code..so many 'paths' and so much information to attend to.. I will have at it..

Is the IAT is at the module entry point of the 'first' dll in memory I would come across...I need to 'test' with msvcrt loaded and user32 and support others to verify 'behavior'..

because if this is the case a functional 'GetApi' and IAT parsing of kernel32 on XP is as simple as get module base add 1000h in esi lodsd push eax cmp eax,0 jg lodsd... But it might just be better to include another parser...cause I want to be able to cross reference data to functions.. And yes I know this is 'already' done.. o0 almost every thing has been 'done' to the extent of thinking at the time of inception and implementation, So that leaves me here now..still with questions..and guestions.. that is ' your line..' ..'knowing' the answers before the guestions 'come'.. that is not a good standpoint, for the more you 'think you know how to deal with 'it' the less you think on how to amalgamate it..o0.

![Ry4n.4pr1l]!
May 2nd, 2011, 00:41
Code:

;This code is written by Ryan April and is the basis of a crack in intels sysenter instruction I researched with the spurring of Indy...
;FREE As IS and is to be used for educational purposes only...DONT Use on AMD.. Im working on syscall but there is only 1 post about syscall o0 (way back)..yet I see how to do it with 'ecx'..

I hold nothing against anyone..maybe if you questioned more you would receive more..
.486
.model flat,stdcall
option casemap:NONE
option offset:SEGMENT
zregs SEGMENT DWORD flat PUBLIC 'text'
assume fs:nothing
ZeroRegister:
jmp FixFromBelow
ZeroRegisters:;This zero's registers,no information is available.. o0
xor ebx,ebx;0 ebx
mov eax,ebx;0 eax
mov ecx,ebx;0 ecx
mov edx,ebx;0 edx
mov esi,ebx;0 esi
mov edi,ebx;0 edi
;hot patch to ret
AAA;adjust asci for addition..;nop
NotAPE:
xor edx,edx;clear edx if PE is not detected
;hot patch..
AAA;nop
IfIsAPE:
cmp word ptr [edx],05a4dh;test for MZ
jne NotAPE;jump not equal
;hot patch
AAA;nop
MZ2PE:
sub edx,-03ch;base of Image to PE
;hotpatch..
AAA;nop
FixFromAbove:
pop edx;get return address
push edx;restore return address
GetEntry:
dec dx;decrease lower word
xor dl,dl;clear lowest byte
cmp word ptr [edx],044ebh;find my entry point
jne GetEntry;f test failed go back 1xxh
push edx;store ep on stack
pop esi;Get ep from stack
;hotpatch..
AAA;nop
A3update2Ret:
push 37h;store my hotpatch byte on stack
pop ebp;get it off stack.
Fixup:
cmp esi,[esp];compare esi to return address
jg @f;if greater jmp to ret
lodsb ;\
cmp ax,bp;find AAA to patch
jne Fixup ;/
add byte ptr [esi-1],08ch;overwrite it with ret
cmp esi,[esp];compare esi return address
jl Fixup;if less then continue patching
@@:
AAA
FixFromBelow:
call FixFromAbove;place a return address on the stack.. o0
sub ebx,ebx;0;
dec ebx;0ffffffffh
push ebx
push ebx
pop eax;as above 0ffffffffh
pop edi;as above 0ffffffffh
sub ebx,-5h;add 5 to 0ffffffff which makes 4
sub esp,esp;0
xor esp,dword ptr fs:[ebx];stack limit
mov ebp,edx;mov entry to ebp
pushad;context store
sub edx,-2h;entry +2
call edx;zeroregisters
jmp FireItUp
VersionTrap:
sub ecx,-4h;4
sub dh,-3;
ror dx,cl;30h
xor esi,fs:[edx];read the peb o0
sub esi,-74h
add esi,edx;+a4
inc ecx;5
inc ecx;6
lodsb;read byte from esi
cmp al,cl;check for vista
je vista
sub esi,-3h
xor ecx,ecx
test_version:
cmp ecx,dword ptr [esi];check subversion for 2k XP and 2k3...
je VersionLdr
inc ecx;inc version
jmp test_version
vista:
add ecx,-3
VersionLdr:
inc ecx;inc 1 for proper index loading
add ebx,-4
mov esi,ebx
@@:
lodsb;read the proper index byte for 2k ~ vista
loopd @b;loop according to ecx value
FoundIndex:
ret
FireItUp:
mov ebx,esp
push 02f1b1918h;ntclose indexs
add ebp,064h
call ebp;version trap NtClose indexes
;This is not in practical use yet.. Im working on 'locating' RtlAddVectoredException Handler and adding Indy's marvelous Singlestep ability.
;So that I can just single step analyze dynamically error codes...
;and 'induce' hysteria by finding out we are 'close to' 40% retrovirus in our DNA. also 1~4% nearnderthal..if you are of european decent.. xD

mov esi,ecx;cleanup
mov edx,ecx;cleanup
jmp OverData
I_NT:;My own personal answer to beating not having a 'ldr' to rely on..
mov eax,ebx
db 0e8h
dd 0fffffffah
ret
;\
dd 0ffffffffh;ntdll base address
;/
dd 0fffffff1h,0fffffff2h
Data_endings:
pop esi;get return address off of stack..
push esi ;push it back on
ret
SysEnter:
inc edi
mov eax,edi
mov esp,edx
dw 340fh
OverData:
call Data_endings
FuzzSysEnter:
test edx,edx
js FuzzIt
jz FuzzIt
xor dx,dx;ntdll
sub ebp,052h
call ebp; IfIsAPE
test edx,edx
jnz found_dll
inc_edi:
inc edi
jmp FuzzSysEnter
FuzzIt:
cmp edi,ebp
je inc_edi
mov edx,esi
sub edx,13h
add esi,-5h
mov dword ptr [edx],esi
mov dword ptr[edx-4],esp
mov esi,edx
jmp SysEnter
found_dll:
call I_NT
mov esi,dword ptr [esp-8h];read the return address of the first call
inc esi;add 1 to get the 'data' address
mov dword ptr [esi],edx;store imagebase in code
xor cl,cl;get module base addess
mov dword ptr [esp-8h],ecx
mov esp,ebx
ParseReloc:
mov edi,edx
mov esi,edx;
xor esi, dword ptr [edx+3ch];add PE offset to imagebase
sub esi,-0a4h;add a4..
mov ebx,dword ptr [esi];read reloc size from PE ebx
add esi,-4h
add edx,dword ptr [esi];add reloc offset to imagebase
mov esi,edx
next_section:
test ebx,ebx;finished parsing relocations?
jz TakeFurtherAction
lodsd;read offset from imagebase to get proper relocation
mov edx,eax;store in edx
lodsd;read number of relocations for that offset
sub ebx,eax;minus that from total number of relocations
sub eax,8h;minus the size of IMAGE_BASE_RELOC structure from total number of relocations for this offset
mov ecx,eax;store the result in the count
xor bp,bp
sub bp,-3h
rol bp,-4h
find_data:
mov eax,edi;rewrite image base to eax each loop
lodsw;add reloc entry to imagebase
xor ax,bp;remove entry type from entry
add eax,edx;add image offset from base
push eax;store parsed entry onto stack
dec ecx
dec ecx
cmp ecx,2;check if we are 2 away from next section(0000)
jne find_data;loop
inc esi
inc esi
jmp next_section;goto next relocation entry
TakeFurtherAction:
mov ebx,esp
@@:
pop edx
mov edx,[edx];NAME that symbol..by reading it.. logically speaking of course..
cmp edx,edi;test if we find a address that is less then the image base address
jg @b
xor dx,dx;clear lower
dec edx;make ffff
test edx,edx
js OutOfThisLoop
xor dx,dx;clear lower
mov edi,edx;edx = kernel32.dll
mov esp,ebx;dont overwrite entries
call ParseReloc;parse the relocation table..
OutOfThisLoop:;oh noes..I got bored of commenting..o0
mov edx,[esp-4]
xor dl,dl
dec dx
sub dl,-3h
mov esp,ebx
call edx
mov esi,[esp]
dec edx
xor dx,dx
ror edx,-4
xor dx,dx
and esi,edx
mov edi,esi
sub edi,-03ch
mov di,word ptr [edi]
sub edi,-0d8h
xor si,word ptr [edi]
mov edi,esi
PilferTable:
lodsd
push eax
cmp eax,ecx
jne PilferTable
ZeroItOut:
xor edx,edx
mov ebp,edx
sub ebp,-4
TestInterModularCall:
lodsd
add eax,esi;ethenol for your mind,and absynth for the soul..
cmp eax,edi
jl ByteScan;non null compliant fix is simple.. move the bytescan code above this..
mov edx,edi
xor dx,dx
sub edx, -03ch
mov dx,word ptr [edx]
add edx,dword ptr [edx+50h]
xor dl,dl
dec dx
cmp eax,edx
jg ByteScan
push esi
mov esi,eax
lodsw
cmp ax,0ff8bh
jne @f
lodsb
cmp al,055h
jne @f
lodsw
cmp ax,0ec8bh
jne @f
lodsb
cmp al,056h
jne @f
lodsw
cmp ax,0358bh
jne @f
lodsd;VirtualProctectEx call for NtProtectVirtualMemory
mov esi,eax
lodsd;ntdlls Sycall table entry for above api..
;below.. is something that piotr said was hard.. o0 wtf.. I made a lower case b..almost..
mov ebx,eax
xor bx,bx
sub esp,1ch
mov ebp,esp
add ebp,14h
xor edx,edx
add edx,59h
add edx,59h
sub ecx,-0ch
rol edx,cl
xor ecx,ecx
mov dword ptr [esp],-1
mov dword ptr [ebp+ecx],ebx
mov dword ptr [esp+4],ebp
mov dword ptr [ebp+ecx+4],edx
add ebp,4
mov dword ptr [esp+8h],ebp
add ecx,4
mov dword ptr [esp+0Ch],ecx
add ebp,4
mov dword ptr [ebp+ecx],ecx
mov [esp+10h],ebp
call eax
@@:
pop esi
ByteScan:
lodsb
cmp al,0e8h
je TestInterModularCall
jmp ByteScan
IFailz:
ret
end ZeroRegister
zregs ends

Indy
May 7th, 2011, 06:28
![Ry4n.4pr1l]!
Good obfuscation

Indy
May 17th, 2011, 16:44
Definition of base and limit the module:
Code:
%NTCALL macro Id
mov eax,Id
mov edx,esp
Int 2Eh
endm

QueryImageSize proc uses ebx Address:PVOID
xor ebx,ebx
push -4
push -4
Id:
%NTCALL Ebx
cmp eax,STATUS_INVALID_ADDRESS
je @f
inc ebx
cmp ebx,1000H
jb Id
xor eax,eax
xor ecx,ecx
jmp Exit
@@:
push Address
push Address
%NTCALL Ebx
test eax,eax
jz @f
add esp,2*4
jmp Id
@@:
and dword ptr [esp],NOT(PAGE_SIZE*16 - 1)
@@:
sub dword ptr [esp],PAGE_SIZE*16
; Base
%NTCALL Ebx
test eax,eax
jz @b
add dword ptr [esp],PAGE_SIZE*16
; Limit
and dword ptr [esp + 4],NOT(PAGE_SIZE - 1)
@@:
add dword ptr [esp + 4],PAGE_SIZE
%NTCALL Ebx
test eax,eax
jz @b
pop eax
pop ecx
Exit:
add esp,2*4
ret
QueryImageSize endp

Entry proc
Call $+5
Call QueryImageSize
ret
Entry endp


How does it work ?

![Ry4n.4pr1l]!
May 18th, 2011, 15:58
That was fun..I know most of 'this', I just focused on the funner parts of this code that I didnt quite understand..

I got this to compile..I used:
MODEL:flat,SYSCALL
PAGE_SIZE = 1000h..

'compiled code looks like this'
Code:

CPU Disasm
Address Hex dump Command Comments
00401000 /$ 55 PUSH EBP
00401001 |. 8BEC MOV EBP,ESP
00401003 |. 53 PUSH EBX
00401004 |. 33DB XOR EBX,EBX
00401006 |. 6A FC PUSH -4
00401008 |. 6A FC PUSH -4
0040100A |> 8BC3 /MOV EAX,EBX
0040100C |. 8BD4 |MOV EDX,ESP
0040100E |. CD 2E |INT 2E
00401010 |. 3D 410100C0 |CMP EAX,C0000141
00401015 |. 74 0F |JE SHORT 00401026
00401017 |. 43 |INC EBX
00401018 |. 81FB 00100000 |CMP EBX,1000
0040101E |.^ 72 EA |JB SHORT 0040100A
00401020 |. 33C0 |XOR EAX,EAX
00401022 |. 33C9 |XOR ECX,ECX
00401024 |. EB 50 |JMP SHORT 00401076
00401026 |> FF75 08 |PUSH DWORD PTR SS:[ARG.1]
00401029 |. FF75 08 |PUSH DWORD PTR SS:[ARG.1]
0040102C |. 8BC3 |MOV EAX,EBX
0040102E |. 8BD4 |MOV EDX,ESP
00401030 |. CD 2E |INT 2E
00401032 |. 85C0 |TEST EAX,EAX
00401034 |. 74 05 |JE SHORT 0040103B
00401036 |. 83C4 08 |ADD ESP,8
00401039 |.^ EB CF \JMP SHORT 0040100A
0040103B |> 812424 0000FF AND DWORD PTR SS:[LOCAL.5],FFFF0000
00401042 |> 812C24 000001 /SUB DWORD PTR SS:[LOCAL.5],10000
00401049 |. 8BC3 |MOV EAX,EBX
0040104B |. 8BD4 |MOV EDX,ESP
0040104D |. CD 2E |INT 2E
0040104F |. 85C0 |TEST EAX,EAX
00401051 |.^ 74 EF \JE SHORT 00401042
00401053 |. 810424 000001 ADD DWORD PTR SS:[LOCAL.5],10000
0040105A |. 816424 04 00F AND DWORD PTR SS:[LOCAL.4],FFFFF000
00401062 |> 814424 04 001 /ADD DWORD PTR SS:[LOCAL.4],1000
0040106A |. 8BC3 |MOV EAX,EBX
0040106C |. 8BD4 |MOV EDX,ESP
0040106E |. CD 2E |INT 2E
00401070 |. 85C0 |TEST EAX,EAX
00401072 |.^ 74 EE \JE SHORT 00401062
00401074 |. 58 POP EAX
00401075 |. 59 POP ECX
00401076 |> 83C4 08 ADD ESP,8
00401079 |. 5B POP EBX
0040107A |. C9 LEAVE
0040107B \. C3 RETN
0040107C /. E8 00000000 CALL 00401081
00401081 |$ E8 7AFFFFFF CALL 00401000
00401086 |. C3 RETN


totally less obfuscation..

The code explains itself..But you want my explanation..ok.

Code:

@@:
add dword ptr [esp + 4],PAGE_SIZE;increment 1000h
%NTCALL Ebx;use NtAllocateVirtualMemory to find the ImageSizeOf Kernel32 in memory..
...
ret
_Entry proc
Call $+5
Call QueryImageSize
;at ret this function is called with ExitThread function being the parameter of the call
ret

Indy
May 18th, 2011, 22:29
![Ry4n.4pr1l]!
This service NtAreMappedFilesTheSame

![Ry4n.4pr1l]!
May 19th, 2011, 14:10
NtAreMappedFilesTheSame takes 2 parameters to check if p2 is in the area of mapped memory of p1.. By pushing in 2 invalid addresses you force the error to occur and the status STATUS_INVALID_ADDRESS is used to find that specific API.

You then find the base address of the program in memory and test if the next page is part of the memory for the file..It succeeds at xxxx1000 and fails at xxxx2000 because the memory map of the loaded module ends.The first run the Image being tested is the module itself that is current loaded and running..The next pass is called with ExitProcess routine and its base and limit are tested in the same manner but it ends at
the limit of kernel32.dll..

great stuff..even though some of my analysis was flatly wrong with the API being used..That's my fault, I didn't even see the highlight index button .. I'm usually 'more' correct the 2nd time though..o0

Thanks for the correction !

regards Ry4n

![Ry4n.4pr1l]!
May 21st, 2011, 13:15
"IT IS TIME"..And you thought different..
"Enjoy what has been written and try to understand it, as it applies to you"..
"LOVE IT AND EVERY MOMENT SPENT WITH IT".. for it loves you just as much.

"In that I found that the End is only a new beginning."

@JMI: I am sorry for my misuse of my searching capabilities..The words I say are not meant to cause confusion, they are meant to cause that little light bulb inside everyone's brain to shine more brightly..I only hope to hear more from you, and I will try never to exploit the blinding power of anger in the seeking of information, if there is more that you would require of me to do or explain..'simply ask'..

I find base and limit of every file map in the currently executing process be that my process or a process that is injected with this dll or loads it..Now just need a way to sort the output of this information...

So now I think I might have toyed with this API enough to fully understand its capabilities and limitations. I made a implementation that works as a process and a dll..

Code:

.686
.model flat,syscall
option casemap:none
.data
IFound dword 0
SIndex dword 0
EIndex dword 0
MRStart dword 0ffh dup (0)
MREnd dword 0ffh dup (0)
.code
_Entry proc
mov edi,dword ptr [esp];store next execution phase is edi
sub edx,edx;0
inc edx;1
rol edx,0ch;1000h
dec edx;000000fffh
rol edx,14h;0fff00000h
and edi,edx;base address of kernel32(exe format),ntdll(dll format)..
lea edx,MRStart;Get Module Range Start array..
mov dword ptr [edx],edi;write kernel32 base address to first entry
inc [SIndex];SIndex = 1
mov dword ptr [esp-8], edi;store the base addresses to the stack
mov dword ptr [esp-4], edi
sub esp,8
sub ebx,ebx;0
@@:
inc ebx;increment until STATUS_SUCCESS
Int2e:
mov eax,ebx; index to eax
mov edx,esp;stack to edx
int 2eh;execute interrupt for current Index
test eax,eax;test for status success
jnz @b;if not STATUS_SUCCESS go back to increment
mov IFound,ebx;store the index of NtAreMappedFilesTheSame
jmp @f
StoreEnd:
mov ebx,[EIndex];Get Memory Range End Index
cmp [SIndex],ebx;compare SIndex to ebx
je @f;if index is equal the dont write entry and add another page.
mov eax,dword ptr [esp+4];store Range End in eax
lea edx,MREnd;Get Effective address or MREnd array
mov ecx,[EIndex];Set ecx equal to End index
mov dword ptr [edx+ecx*4],eax;write entry to MREnd + EIndex * 4
inc [EIndex];post increment Index
jmp @f
GetDeviceLength:
mov eax,[IFound];Set eax to Index of NtAreMappedFilesTheSame
mov edx,esp;store stack to edx
int 2eh;Call NtAreMappedFilesTheSame
test eax,eax;test for STATUS_SUCCESS
jz @f;if SUCCESS, increment a page
cmp al,41h;compare al to 41h(STATUS_INVALID_ADDRESS)
je StoreEnd;
cmp al,0d4h;compare al to d4h(STATUS_NOT_SAME_DEVICE)
je NewDeviceFound
@@:
sub edx,edx;0
inc edx;1
rol edx,0ch;1000h
add dword ptr [esp+4],edx;add page size to current the 2nd parameter..
jmp GetDeviceLength;go back
NewDeviceFound:
mov edi,dword ptr [esp+4];Get new Memory Mapped File to edi
lea edx,MRStart;move edx Memory Range Start
cmp edi,[edx];compare if new Memory Mapped File to the first entry to check for loopyness
je EndThis
mov eax,[SIndex]
mov dword ptr [edx+eax*4],edi
mov dword ptr [esp],edi
mov dword ptr [esp+4],edi
inc [SIndex]
jmp @b
EndThis:
add esp,8
mov eax,1
ret
_Entry EndP
end


@Indy: amazing you are.