sha0coder/scemu

TLS callbacks not being executed

Closed this issue · 18 comments

 $ RUST_BACKTRACE=1 cargo run --release -- -vv -6 -f /Users/brandonros/Downloads/redacted.exe 
    Finished release [optimized] target(s) in 0.04s
     Running `target/release/scemu -vv -6 -f /Users/brandonros/Downloads/redacted.exe`
initializing regs
loading memory maps
memory test Ok.
PE64 header detected.
no import directory at va 0xc4f.
IAT Bound started ...
IAT Bound.
Loaded /Users/brandonros/Downloads/redacted.exe
	11 sections  base addr 0x140000000
	created pe32 map for section `.text` at 0x140001000 size: 10524854
	entry point at 0x144901722  0x4901722 
	created pe32 map for section `.rdata` at 0x140a0b000 size: 32899160
	created pe32 map for section `.data` at 0x14296c000 size: 371428
	created pe32 map for section `.pdata` at 0x1429c7000 size: 232872
	created pe32 map for section `.qtmetad` at 0x142a00000 size: 1334
	created pe32 map for section `.qtmimed` at 0x142a01000 size: 322789
	created pe32 map for section `.tls` at 0x142a50000 size: 24
	created pe32 map for section `.jPc0` at 0x142a51000 size: 5392274
	created pe32 map for section `.jPc1` at 0x142f76000 size: 6456
	created pe32 map for section `.jPc2` at 0x142f78000 size: 34504780
/!\ warning: raw sz:34786304 off:34512896 sz:273408  off+sz:34786304
	created pe32 map for section `.rsrc` at 0x145061000 size: 273368
 ----- emulation -----
1 0x144901722: push  0FFFFFFFFA2F395ECh ;0xffffffffa2f395ec 
2 0x144901727: call  0000000144F2FAF1h
3 0x144f2faf1: push  r11 ;0x0 
4 0x144f2faf3: movzx r11,sp
5 0x144f2faf7: push  rbx ;0xda6f566156ae77e1 
6 0x144f2faf8: movsx ebx,si
7 0x144f2fafb: push  rax ;0x7b106ba6af5f7353 
8 0x144f2fafc: pushfq
9 0x144f2fafd: rcr   bx,cl
10 0x144f2fb00: cmc
11 0x144f2fb01: bsf   ebx,r15d
12 0x144f2fb05: push  rsi ;0x3105dab61acd9c89 
13 0x144f2fb06: push  rdi ;0xf7b3fc465af8e94 
14 0x144f2fb07: clc
15 0x144f2fb08: shld  r11w,r14w,46h
16 0x144f2fb0e: shr   rbx,94h
17 0x144f2fb12: push  rbp ;0x22f000 
18 0x144f2fb13: push  r8 ;0x0 
19 0x144f2fb15: push  r13 ;0x0 
20 0x144f2fb17: cmp   r13b,0D6h
	cmp: 0x0 < 0xd6
21 0x144f2fb1b: push  r14 ;0x0 
22 0x144f2fb1d: btc   si,16h
23 0x144f2fb22: cmp   rbx,4AD720F8h
	cmp: 0x0 < 0x4ad720f8
24 0x144f2fb29: push  r15 ;0x0 
25 0x144f2fb2b: push  r12 ;0x0 
26 0x144f2fb2d: shl   sil,cl
27 0x144f2fb30: inc   si
28 0x144f2fb33: push  r10 ;0x0 
29 0x144f2fb35: btr   bx,4Fh
30 0x144f2fb3a: push  rcx ;0x1e52b41f0aaefa99 
31 0x144f2fb3b: push  rdx ;0x52f6cbf049453185 
32 0x144f2fb3c: sar   eax,cl
33 0x144f2fb3e: push  r9 ;0x0 
34 0x144f2fb40: xchg  dh,bh
35 0x144f2fb42: shl   rdx,cl
36 0x144f2fb45: cwd
37 0x144f2fb47: mov   r9,0
38 0x144f2fb51: cmova bx,di
39 0x144f2fb55: push  r9 ;0x0 
40 0x144f2fb57: sar   r11w,0A9h
41 0x144f2fb5c: cmc
42 0x144f2fb5d: mov   rsi,[rsp+90h]
43 0x144f2fb65: rcr   r11,0C3h
44 0x144f2fb69: add   esi,7EF34DA5h
45 0x144f2fb6f: cqo
46 0x144f2fb71: rcl   dx,69h
47 0x144f2fb75: rol   esi,2
48 0x144f2fb78: movzx edx,bp
49 0x144f2fb7b: rdtsc
50 0x144f2fb7d: bswap esi
51 0x144f2fb7f: movsx r11d,bp
52 0x144f2fb83: cmovnp ebx,r15d
53 0x144f2fb87: inc   esi
54 0x144f2fb89: movsx r8w,bl
55 0x144f2fb8e: btc   r8w,r8w
56 0x144f2fb93: add   rsi,r9
57 0x144f2fb96: mov   r9,100000000h
58 0x144f2fba0: ror   r8,cl
59 0x144f2fba3: rcr   r8b,48h
60 0x144f2fba7: lea   rsi,[rsi+r9]
61 0x144f2fbab: test  di,17CEh
62 0x144f2fbb0: clc
63 0x144f2fbb1: bt    r8,0CDh
64 0x144f2fbb6: mov   rbx,rsp
65 0x144f2fbb9: dec   r11b
66 0x144f2fbbc: sub   rsp,180h
67 0x144f2fbc3: or    r11b,3Ch
68 0x144f2fbc7: shl   r11,cl
69 0x144f2fbca: and   rsp,0FFFFFFFFFFFFFFF0h
70 0x144f2fbd1: bsr   dx,dx
71 0x144f2fbd5: xor   al,r14b
72 0x144f2fbd8: shrd  ax,r9w,0FBh
73 0x144f2fbde: mov   r11,rsi
74 0x144f2fbe1: xadd  r8b,dl
75 0x144f2fbe5: mov   rdx,0
76 0x144f2fbef: bswap r8d
77 0x144f2fbf2: shl   rax,cl
78 0x144f2fbf5: sub   r11,rdx
79 0x144f2fbf8: lea   r8,[144F2FBF8h]
80 0x144f2fbff: cwde
81 0x144f2fc00: ror   ax,cl
82 0x144f2fc03: sub   rsi,4
83 0x144f2fc0a: add   al,0A8h
84 0x144f2fc0c: movsx eax,bp
85 0x144f2fc0f: movzx eax,di
86 0x144f2fc12: mov   eax,[rsi]
/!\ error dereferencing dword on 0x22718e41
exception without any SEH handler nor vector configured.

image

looks a bit different than x64dbg trace? not sure if it is going entry point -> tls callback0 -> tlscallback 1 -> tls callback 2 in order?

Yep, TLS Callback 1 is being called before EntryPoint. Does that make sense? Is that an easy fix to implement?

Type     Address          Module/Label/Exception         State    Disassembly              H Summary         
Software                                                                                     
         00000001448A76A4 redacted.exe              One-time push 1DB36B3A            0 TLS Callback 1
         00000001400D5FA0 redacted.exe              One-time add byte ptr ds:[rax],al 0 TLS Callback 2
         00000001400D6020 redacted.exe              One-time add byte ptr ds:[rax],al 0 TLS Callback 3
         0000000144901722 <redacted.exe.EntryPoint> One-time push FFFFFFFFA2F395EC    0 entry breakpoint

The current implementation is very basic just uses a tls vector and support some tls api.

For doing this well it is necessary to craft a TEB structure from scratch with its TLS item, instead of using the teb map,
Then parsing .tls section, I have to document myself more about tls to do it at lowlevel implementing it well.
It seems not difficult to do apparently.

#[derive(Debug)]
pub struct TEB {
    reserved1: [u32;12],
    peb: u32,
    reserved2: [u32;399],
    reserved3: [u8;1952],
    tls_slots: [u32;64],
    reserved4: [u8;8],
    reserved5: [u32;26],
    reserved_for_ole: u32,
    reserved6: [u32;4],
    tls_expansion_slots: u32,
}

I fixed the IAT binding of pe64 loading, and now this binary is loading 21 dll's
apps are bigger than malware usually and uses more dlls and apis, apps itself are out of scope.
I added the 21 dlls and prepare tls structures:

~/s/scemu ❯❯❯ target/release/scemu -f  bin64/DTS9_PatcherV.exe -6
use -vv to see the assembly code emulated, and -v to see the messages
initializing regs
loading memory maps
memory test Ok.
PE64 header detected.
IAT binding started ...
Loaded maps64/api-ms-win-crt-heap-l1-1-0.dll
        2 sections, base addr 0x180000000
        created pe64 map for section `.rdata` at 0x180001000 size: 1576
        created pe64 map for section `.rsrc` at 0x180002000 size: 1008
Loaded maps64/api-ms-win-crt-private-l1-1-0.dll
        2 sections, base addr 0x180000000
        created pe64 map for section `.rdata` at 0x180001000 size: 53160
        created pe64 map for section `.rsrc` at 0x18000e000 size: 1008
Loaded maps64/api-ms-win-crt-runtime-l1-1-0.dll
        2 sections, base addr 0x180000000
        created pe64 map for section `.rdata` at 0x180001000 size: 5448
        created pe64 map for section `.rsrc` at 0x180003000 size: 1008
Loaded maps64/api-ms-win-crt-stdio-l1-1-0.dll
        2 sections, base addr 0x180000000
        created pe64 map for section `.rdata` at 0x180001000 size: 7028
        created pe64 map for section `.rsrc` at 0x180003000 size: 1008
Loaded maps64/api-ms-win-crt-string-l1-1-0.dll
        2 sections, base addr 0x180000000
        created pe64 map for section `.rdata` at 0x180001000 size: 7156
        created pe64 map for section `.rsrc` at 0x180003000 size: 1008
Loaded maps64/api-ms-win-crt-environment-l1-1-0.dll
        2 sections, base addr 0x180000000
        created pe64 map for section `.rdata` at 0x180001000 size: 1084
        created pe64 map for section `.rsrc` at 0x180002000 size: 1008
Loaded maps64/shell32.dll
        6 sections, base addr 0x7ff788c0000
        created pe64 map for section `.text` at 0x7ff788c1000 size: 4376688
        created pe64 map for section `.rdata` at 0x7ff78cee000 size: 728164
        created pe64 map for section `.data` at 0x7ff78da0000 size: 38112
        created pe64 map for section `.pdata` at 0x7ff78daa000 size: 302580
        created pe64 map for section `.rsrc` at 0x7ff78df4000 size: 8670296
/!\ warning: raw sz:14174208 off:14112768 sz:61440  off+sz:14174208
        created pe64 map for section `.reloc` at 0x7ff79639000 size: 61312
Loaded maps64/api-ms-win-crt-math-l1-1-0.dll
        2 sections, base addr 0x180000000
        created pe64 map for section `.rdata` at 0x180001000 size: 9900
        created pe64 map for section `.rsrc` at 0x180004000 size: 1008
Loaded maps64/api-ms-win-crt-convert-l1-1-0.dll
        2 sections, base addr 0x180000000
        created pe64 map for section `.rdata` at 0x180001000 size: 4868
        created pe64 map for section `.rsrc` at 0x180003000 size: 1008
Loaded maps64/api-ms-win-crt-time-l1-1-0.dll
        2 sections, base addr 0x180000000
        created pe64 map for section `.rdata` at 0x180001000 size: 3280
        created pe64 map for section `.rsrc` at 0x180002000 size: 1008
Loaded maps64/uxtheme.dll
        6 sections, base addr 0x7ff72ee0000
        created pe64 map for section `.text` at 0x7ff72ee1000 size: 250932
        created pe64 map for section `.rdata` at 0x7ff72f1f000 size: 45064
        created pe64 map for section `.data` at 0x7ff72f2b000 size: 11552
        created pe64 map for section `.pdata` at 0x7ff72f2e000 size: 19092
        created pe64 map for section `.rsrc` at 0x7ff72f33000 size: 4304
/!\ warning: raw sz:332288 off:331264 sz:1024  off+sz:332288
        created pe64 map for section `.reloc` at 0x7ff72f35000 size: 656
Loaded maps64/netapi32.dll
        6 sections, base addr 0x7ff70b60000
        created pe64 map for section `.text` at 0x7ff70b61000 size: 41673
        created pe64 map for section `.rdata` at 0x7ff70b6c000 size: 23664
        created pe64 map for section `.data` at 0x7ff70b72000 size: 1944
        created pe64 map for section `.pdata` at 0x7ff70b73000 size: 1332
        created pe64 map for section `.rsrc` at 0x7ff70b74000 size: 1016
/!\ warning: raw sz:72704 off:72192 sz:512  off+sz:72704
        created pe64 map for section `.reloc` at 0x7ff70b75000 size: 52
Loaded maps64/api-ms-win-crt-filesystem-l1-1-0.dll
        2 sections, base addr 0x180000000
        created pe64 map for section `.rdata` at 0x180001000 size: 3016
        created pe64 map for section `.rsrc` at 0x180002000 size: 1008
Loaded maps64/userenv.dll
        7 sections, base addr 0x7ff70720000
        created pe64 map for section `.text` at 0x7ff70721000 size: 68936
        created pe64 map for section `.orpc` at 0x7ff70732000 size: 68
        created pe64 map for section `.rdata` at 0x7ff70733000 size: 23808
        created pe64 map for section `.data` at 0x7ff70739000 size: 2720
        created pe64 map for section `.pdata` at 0x7ff7073a000 size: 3636
        created pe64 map for section `.rsrc` at 0x7ff7073b000 size: 5592
/!\ warning: raw sz:109056 off:108032 sz:1024  off+sz:109056
        created pe64 map for section `.reloc` at 0x7ff7073d000 size: 560
Loaded maps64/api-ms-win-crt-utility-l1-1-0.dll
        2 sections, base addr 0x180000000
        created pe64 map for section `.rdata` at 0x180001000 size: 1396
        created pe64 map for section `.rsrc` at 0x180002000 size: 1008
Loaded maps64/version.dll
        6 sections, base addr 0x7ff700f0000
        created pe64 map for section `.text` at 0x7ff700f1000 size: 17000
        created pe64 map for section `.rdata` at 0x7ff700f6000 size: 5224
        created pe64 map for section `.data` at 0x7ff700f8000 size: 2330
        created pe64 map for section `.pdata` at 0x7ff700f9000 size: 1080
        created pe64 map for section `.rsrc` at 0x7ff700fa000 size: 1056
/!\ warning: raw sz:29184 off:28672 sz:512  off+sz:29184
        created pe64 map for section `.reloc` at 0x7ff700fb000 size: 16
Loaded maps64/api-ms-win-crt-locale-l1-1-0.dll
        2 sections, base addr 0x180000000
        created pe64 map for section `.rdata` at 0x180001000 size: 1404
        created pe64 map for section `.rsrc` at 0x180002000 size: 1008
Loaded maps64/winmm.dll
        7 sections, base addr 0x7ff71cc0000
        created pe64 map for section `.text` at 0x7ff71cc1000 size: 153374
        created pe64 map for section `.rdata` at 0x7ff71ce7000 size: 24868
        created pe64 map for section `.data` at 0x7ff71cee000 size: 12712
        created pe64 map for section `.pdata` at 0x7ff71cf2000 size: 8772
        created pe64 map for section `.guids` at 0x7ff71cf5000 size: 16
        created pe64 map for section `.rsrc` at 0x7ff71cf6000 size: 16000
/!\ warning: raw sz:217600 off:217088 sz:512  off+sz:217600
        created pe64 map for section `.reloc` at 0x7ff71cfa000 size: 304
Loaded maps64/wtsapi32.dll
        6 sections, base addr 0x7ff70580000
        created pe64 map for section `.text` at 0x7ff70581000 size: 36489
        created pe64 map for section `.rdata` at 0x7ff7058a000 size: 9268
        created pe64 map for section `.data` at 0x7ff7058d000 size: 2276
        created pe64 map for section `.pdata` at 0x7ff7058e000 size: 1620
        created pe64 map for section `.rsrc` at 0x7ff7058f000 size: 1080
/!\ warning: raw sz:54272 off:53760 sz:512  off+sz:54272
        created pe64 map for section `.reloc` at 0x7ff70590000 size: 116
Loaded maps64/dwmapi.dll
        6 sections, base addr 0x7ff70f60000
        created pe64 map for section `.text` at 0x7ff70f61000 size: 39147
        created pe64 map for section `.rdata` at 0x7ff70f6b000 size: 10992
        created pe64 map for section `.data` at 0x7ff70f6e000 size: 12768
        created pe64 map for section `.pdata` at 0x7ff70f72000 size: 2880
        created pe64 map for section `.rsrc` at 0x7ff70f73000 size: 14040
/!\ warning: raw sz:82432 off:81920 sz:512  off+sz:82432
        created pe64 map for section `.reloc` at 0x7ff70f77000 size: 80
Loaded maps64/api-ms-win-crt-multibyte-l1-1-0.dll
        2 sections, base addr 0x180000000
        created pe64 map for section `.rdata` at 0x180001000 size: 8712
        created pe64 map for section `.rsrc` at 0x180004000 size: 1008
IAT Bound.
Loaded shellcodes64/DTS9_PatcherV.exe
        11 sections, base addr 0x140000000
        created pe64 map for section `.text` at 0x140001000 size: 10524854
        entry point at 0x144901722  0x4901722 
        created pe64 map for section `.rdata` at 0x140a0b000 size: 32899160
        created pe64 map for section `.data` at 0x14296c000 size: 371428
        created pe64 map for section `.pdata` at 0x1429c7000 size: 232872
        created pe64 map for section `.qtmetad` at 0x142a00000 size: 1334
        created pe64 map for section `.qtmimed` at 0x142a01000 size: 322789
        created pe64 map for section `.tls` at 0x142a50000 size: 24
TlsDirectory64 {
    tls_data_start: 0x142f77928,
    tls_data_end: 0x142f77938,
    tls_index: 0x1429b4654,
    tls_callbacks: 0x14496d788,
    zero_fill_size: 0x0,
    characteristic: 0x400000,
}
TLS Callback: 0x1448a76a4
TLS Callback: 0x1400d5fa0
TLS Callback: 0x1400d6020
        created pe64 map for section `.jPc0` at 0x142a51000 size: 5392274
        created pe64 map for section `.jPc1` at 0x142f76000 size: 6456
        created pe64 map for section `.jPc2` at 0x142f78000 size: 34504780
/!\ warning: raw sz:34786304 off:34512896 sz:273408  off+sz:34786304
        created pe64 map for section `.rsrc` at 0x145061000 size: 273368
 ----- emulation -----

very good work. highly appreciated and very
impressive. i am glad i was able to bring a good test to this awesome app you’ve made for a “real world” practical usage.

where is the current hangup now running this app? i will check in a bit as well.

unimplemented instructions or is it executing flawlessly?

TLS Callback: 0x1448a76a4
TLS Callback: 0x1400d5fa0
TLS Callback: 0x1400d6020
	created pe64 map for section `.jPc0` at 0x142a51000 size: 5392274
	created pe64 map for section `.jPc1` at 0x142f76000 size: 6456
	created pe64 map for section `.jPc2` at 0x142f78000 size: 34504780
/!\ warning: raw sz:34786304 off:34512896 sz:273408  off+sz:34786304
	created pe64 map for section `.rsrc` at 0x145061000 size: 273368
 ----- emulation -----
1 0x144901722: push  0FFFFFFFFA2F395ECh ;0xffffffffa2f395ec 
2 0x144901727: call  0000000144F2FAF1h

Built latest + ran it locally. It's parsing TLS Callback, but still running EntryPoint before TlsCallbacks, right?

I'm pretty sure native Windows behavior is parse TLS callbacks, then execute them first before EntryPoint? I'm not sure if they run in sequential order, or separate threads?

I'd expect to be able to override -a 0x1448a76a4 and it overrides rip but I don't think that's working as expected at the moment?

yes all the tls callbacks have to be emulated before the entry point.
Now i did another commit that emulates the tls callbacks before entry point.

But crash on first callback, is accessing to weird memory non mapped
target/release/scemu -f shellcodes64/DTS9_PatcherV.exe -6 -vv --reg rdi
...
Emulating TLS Callback 1
...
84 0x144ff961a: bsf ax,sp
85 rdi: 0x19f82c0af 6971113647
85 0x144ff961e: sub rdi,4
86 rdi: 0x19f82c0ab 6971113643
86 0x144ff9625: mov eax,[rdi]
/!\ error dereferencing dword on 0x19f82c0ab

-a is only working on 32bits, I have to fix it on 64bits.

yes all the tls callbacks have to be emulated before the entry point.

in separate running threads? :/ would it be 4 threads total? 3 TLS callbacks + entrypoint?

But crash on first callback, is accessing to weird memory non mapped

I'll set breakpoint in x32dbg and check. Somewhere in TLSCallback1 it is doing debugger detection and kicking me out but probably not that early on.

image

You probably have a typo somewhere in how it is calculating rdi/where it is coming from.

Should be 0000000144E47256. Trace attached.

rdi-trace.csv

55 | 0000000144FF9625 | 8B07                     | mov eax,dword ptr ds:[rdi]              |                                                   | 0000000144E47256: A4E21BE4E39D6D03-> A4E21BE4E39D |

thanks for the trace, the problem is bswap implementation.

bswap fixed, now is emulating 174 and crash in a register no implemented, tomorrow i will implement it.

renamed this for anybody following along and updating to here for organization

#13

great work, thank you. you keep doing what you do, i will keep testing/helping anyway i can