SEH tricks is not a new Anti-Debugging trick. So many malware already used this to make the manual debugging of its code time consuming and confusing. Today I will share how Gh0strat malware make use of nested SEH exception (try{} catch) as anti-debugging trick to hide its decryption routine.
This article is not to tackle the full C++ Exception Internals, but to share how IDAPRO really helps me in analyzing this type of anti-debugging tricks statically. :)
So lets start!!!
SEH:
![]() |
| figure 1: FS[0] of x32 bit OS |
![]() |
| figure 2: The EXCEPTION_REGISTRATION_RECORD in FS[0] |
When the exception is triggered, control is transfer to the current SEH handler where it will return one of the _EXCEPTION_DISPOSITION members.
Gh0srat: Nested SEH to decrypt its payload:
![]() |
| figure 3: high entropy of data section |
we all know there are so many faster way to bypassed this anti-debugging technique like monitoring the TIB offset 0x0 dynamically for next SEH or dumping process. In our case I will just want to share how IDA PRO will help you a lot in this case in traversing "FuncInfo" structure since IDAPRO resolved most of this SEH structure.
![]() |
| figure 5: first SEH in malware entrypoint |
ehFuncInfo or the exception handler function registered in FS:0 contains some structure that may help us to figure out statically which exception handler function may be call upon the exception is trigger.
![]() |
| figure 8: AddressOfHandler was triggered |
if we follow the call function 0x402200 pushing string address "Shellex" as a parameter. you will notice again that it use another SEH to execute piece of its code. Not like the first SEH, this SEH contains 9 tryblock and HandlerOfAddress like the figure below.
IOC:
yara:
import "pe"
rule gh0st_rat_loader {
meta:
author = "tcontre"
description = "detecting gh0strat_loader"
date = "2021-02-22"
sha256 = "70ac339c41eb7a3f868736f98afa311674da61ae12164042e44d6e641338ff1f"
strings:
$mz = { 4d 5a }
$code = { 40 33 FF 89 45 E8 57 8A 04 10 8A 14 0E 32 D0 88 14 0E FF 15 ?? ?? ?? ?? 8B C6 B9 ?? 00 00 00 }
$str1 = "Shellex"
$str2 = "VirtualProtect"
condition:
($mz at 0) and $code and all of ($str*)
}
rule gh0st_rat_payload {
meta:
author = "tcontre"
description = "detecting gh0strat_payload in memory without MZ header in memory"
date = "2021-02-22"
sha256 = "edffd5fc8eb86e2b20dd44e0482b97f74666edc2ec52966be19a6fe43358a5db"
strings:
$dos = "DOS mode"
$av_str1 = "f-secure.exe"
$av_str2 = "Mcshield.exe"
$av_str3 = "Sunbelt"
$av_str4 = "baiduSafeTray.exe"
$clsid = "{4D36E972-E325-11CE-BFC1-08002BE10318}"
$s1 = "[WIN]"
$s2 = "[Print Screen]"
$s3 = "Shellex"
$s4 = "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0"
$s5 = "%s\\%d.bak"
condition:
($dos at 0x6c) and 2 of ($av_str*) and 4 of ($s*) and $clsid
}




















