首页
论坛
课程
招聘

克图鲁的呼唤

2006-10-28 19:17 10542

克图鲁的呼唤

2006-10-28 19:17
10542
可以用来调用和获取 API ,为 Shellcode(或野猪力量)和壳设计。

不同的内存块开头使用KTULU宏,之后即可用 kcall, kget 宏。

注意不支持转向函数,比如 RtlZeroMemory,不过可以用 kcall 调用 GetProcAddress 来使用他们。

每个 kget/kcall 占用 9 字节,每次调用 ktulu 增加 155 字节(不过你不会经常用吧:{)

你也可以用在普通程序中,会慢一点(不过现在的CPU...),有一定的反反汇编能力(别指望用来加密)。

优化我进行了很久,一开始 400+ 后来 208 后来 168 终于 155,希望高手可以继续进行尺寸优化(我使用了一些比较极端的方法)。这也是我贴出来的主要原因。究竟有没有极限?

一个例子

.386
.model flat, stdcall
option casemap :none

include        KTULU.INC

.DATA
szMsg db "Hello World!",13,10,0

.CODE
START:

KTULU

kget        KiUserExceptionDispatcher
kcall        MessageBoxA, 0, offset szMsg, offset szMsg, 0
kcall        ExitProcess, 0

end START

这是头文件

; ===================
;  THE CALL OF KTULU
; ===================
;
; Coded by forgot/iPB
;
; Size = 155 bytes !!!
;

; EXAMPLE:
;                       KTULU
;                       kget    KiUserExceptionDispatcher
;                       kcall   MessageBoxA, 0, offset szMsg, offset szMsg, 0
;                       kcall   ExitProcess, 0
;                       push    0
;                       kcall   ExitProcess

KTULU                   macro
                        local   core, hash

kcall                   macro   procedure, parameters:VARARG
                        local   reversed, param

reversed                textequ <>

                        %for    param, <parameters>
                        reversed CATSTR <param>, <!,>, reversed
                        endm

                        %for    param, <reversed>
                        push    param
                        endm

                        call    core+2
                        gethash procedure

                        endm

kget                    macro   procedure

                        call    core+2+1
                        gethash procedure

                        endm

gethash                 macro   procedure
                        hash    = 0
                        irpc    c, <procedure>
                        hash    = ((hash shl 7) and 0FFFFFFFFh) or (hash shr (32-7))
                        hash    = hash xor "&c"
                        endm
                        dd      hash
                        endm

core                    proc

                        jmp     __skip1                 ; Two short JMPs save 1 byte
                                                        ;       than a long JMP

                        test    al, 0F9h                ; 0F9H = STC

                        xchg    esi, [esp]
                        lodsd
                        xchg    esi, [esp]

                        pushfd
                        pushad

                        xchg    ebp, eax                ; EBP = Hash

                                                        ; EAX = Kernel32 base
                        db      64h, 0A1h               ; MOV EAX, FS:[30H]
                        dd      30h
                        test    eax, eax
                        jns     __nt_port

                        mov     eax, [eax+34h]
                        mov     eax, [eax+7Ch+3Ch]
                        jmp     __k32_done

__nt_port:              mov     eax, [eax+0Ch]
                        mov     esi, [eax+1Ch]
                        lodsd
                        mov     eax, [eax+08h]

__k32_done:             call    __get_modules           ; EDI = Module list
                        db      'ntdll', 0              ; Add your modules here !!!
                        db      'user32', 0

__skip1:                jmp     __skip2                 ; Hmmmmmmmmmm

__get_modules:          pop     edi

__scan_export:          xchg    ebx, eax                ; EBX = Image base
                                                        ; BL = 0
                        mov     ecx, [ebx+3Ch]
                        mov     ecx, [ebx+ecx+78h]      ; ECX = Export table
                        add     ecx, ebx

                        xor     esi, esi                ; ESI = Index

__check_hash:           lea     eax, [ebx+esi*4]        ; EAX = Name pointer
                        add     eax, [ecx+20h]
                        mov     eax, [eax]
                        cdq                             ; EDX = Calculated hash
                        add     eax, ebx

;此处的cdq上移,我搞错顺序了,谢谢hexer

__calc_hash:            rol     edx, 7
                        xor     dl, [eax]
                        inc     eax
                        cmp     [eax], bl
                        jne     __calc_hash

                        cmp     edx, ebp                ; Check hash
                        jne     __next_index

                        mov     edx, [ecx+24h]          ; EBX = API address
                        add     edx, ebx
                        movzx   edx, word ptr [edx+esi*2]
                        mov     eax, [ecx+1Ch]
                        add     eax, ebx
                        add     ebx, [eax+edx*4]

                        mov     [esp+4*7], ebx          ; Update POPAD.EAX

__exit:                 popad
                        popfd

                        jc      $+2+1
                        push    eax                     ; Jump to API address if CF = 0
                        retn

__next_index:           inc     esi
                        cmp     [ecx+18h], esi
                        jge     __check_hash

__load_module:          push    edi
                        kcall   LoadLibraryA            ; AL = 0

__next_char:            scasb
                        jne     __next_char

                        test    eax, eax
                        jz      __load_module
                        jmp     __scan_export
__skip2:

core                    endp

                        endm

[推荐]看雪企服平台,提供项目众包、渗透测试、安全分析、定制项目开发、APP等级保护等安全服务!

最新回复 (19)
shoooo 16 2006-10-28 19:34
2
0
--------- 由于某人的出现, 该贴内容自动隐藏 ---------
小虾 10 2006-10-28 19:42
3
0
完全不懂啊。
海风月影 17 2006-10-28 19:43
4
0
太牛了,优化得看不懂了
heXer 3 2006-10-28 19:51
5
0
太高深了,不懂
forgot 26 2006-10-28 19:53
6
0
召唤 dwing
binbinbin 28 2006-10-28 20:11
7
0
学习

汇编太难~~
xzchina 1 2006-10-28 20:13
8
0
看不懂!!!!
q3 watcher 2006-10-28 20:22
9
0
MyGetProcAddress原来也写过,但总是会有函数不支持的,要保险的话还是要用GetProcAddress.不过这个写的也太高深了,完全不懂,只能学习! 
kanxue 8 2006-10-28 20:24
10
0
forgot这帖杀伤力很强
girl 1 2006-10-28 20:31
11
0
支持
forgot 26 2006-10-28 20:46
12
0
其实就是编译的时候计算hash
kcall的真实样子是
call core+2
dd hash

core+2处是test al, F9,执行之后CF=0,如果进入core+2+1执行stc
也就是说这两个指令重叠了

获取kernel32用的是ratter的方法,扫peb,有一个mov eax,[eax]变成了lodsd,省1byte

列表优化用了一个假设,调用的api都在表里,所以不设结束标志和判断。
列表推进又用了一个假设(当然是成立的),DLL地址是1000对齐的,AL=0,于是scasb正确执行。

计算hash结束又用到这招,bl=0

最yd得应该算那个分解jmp,一个long jmp 5bytes,2个short jmp 4字节,这个很恶心了。

最后的jc也算一个普遍的技巧把
yiyiguxing 1 2006-10-28 21:45
13
0
有空的话  请多指点指点  免得再生笑话了
太强了!
Isaiah 10 2006-10-28 21:53
14
0
完全不懂~~~
大师兄 2006-10-28 22:33
15
0
标题很艺术,代码看不懂
loveboom 53 2006-10-29 09:39
16
0
七点到现在才看懂一些片段:-(,悄悄的说一下:
__load_module:          push    edi
                        kcall   LoadLibraryA            ; AL = 0

__next_char:            scasb
                        jne     __next_char

                        test    eax, eax
                        jz      __load_module
                        jmp     __scan_export
__skip2:
这样好像总是Load("ntdll.dll"),而不会执行Load("user32.dll")
forgot 26 2006-10-29 12:14
17
0
真的吗?
scasb会edi++
linex 7 2006-10-30 09:54
18
0
膜拜一下!
skyege 2 2006-10-30 12:48
19
0
深了 …………
gkend 2006-10-31 08:14
20
0
不懂,克图鲁什么意思?
游客
登录 | 注册 方可回帖
返回