{
	"id": "60c52b13-ebd1-4a4c-86cf-8bf220a29285",
	"created_at": "2026-04-06T00:21:32.181338Z",
	"updated_at": "2026-04-10T03:21:11.622257Z",
	"deleted_at": null,
	"sha1_hash": "dc049b1e012f71fb39aa3df9365350123b455256",
	"title": "Gh0stRat Anti-Debugging : Nested SEH (try - catch) to Decrypt and Load its Payload",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 719830,
	"plain_text": "Gh0stRat Anti-Debugging : Nested SEH (try - catch) to Decrypt\r\nand Load its Payload\r\nPublished: 2021-02-22 · Archived: 2026-04-05 21:40:47 UTC\r\n SEH tricks is not a new Anti-Debugging trick. So many malware already used this to make the manual debugging\r\nof its code time consuming and confusing. Today I will share how Gh0strat malware make use of nested SEH\r\nexception (try{} catch) as anti-debugging trick to hide its decryption routine.\r\nThis article is not to tackle the full C++ Exception Internals, but to share how IDAPRO really helps me in\r\nanalyzing this type of anti-debugging tricks statically. :)\r\nSo lets start!!!\r\nSEH:\r\nStructure Exception handler (SEH) is one of the classic Anti-debugging tricks used by malware. where it tries to\r\nabuse the mechanism provided by operating system in managing exceptional situation like reference to a non-existence address pointer or execution of code in a read-only page.\r\nThis is done usually  by locating the pointer to SEH linked list in the stack known to be the SEH frame. The\r\ncurrent SEH frame address is located in 0x00 offset relative to the FS (x32 bit) or GS selection (x64 bit).\r\nhttps://tccontre.blogspot.com/2021/02/gh0strat-anti-debugging-nested-seh-try.html\r\nPage 1 of 12\n\nfigure 1: FS[0] of x32 bit OS\r\nfigure 2: The EXCEPTION_REGISTRATION_RECORD in FS[0]\r\nWhen the exception is triggered, control is transfer to the current SEH handler where it will return one of the\r\n_EXCEPTION_DISPOSITION members.\r\nIn this Gh0strat variant it used nested SEH (try{} catch{}) that serve as anti-debugging tricks to make the\r\ndebugging more confusing or let say more time consuming if analyst didn't notice the SEH.\r\nhttps://tccontre.blogspot.com/2021/02/gh0strat-anti-debugging-nested-seh-try.html\r\nPage 2 of 12\n\nGh0srat: Nested SEH to decrypt its payload:\r\nThe sample we will use here contains a big data section where the encrypted gh0strat payload located. we will\r\nnotice that using DIE tool or PE-bear that visualized the size of each section with quite high entropy same as text\r\nsection.\r\nfigure 3: high entropy of data section\r\nwe all know there are so many faster way to bypassed this anti-debugging technique like monitoring the TIB\r\noffset 0x0 dynamically for next SEH or dumping process. In our case I will just want to share how IDA PRO will\r\nhelp you a lot in this case in traversing \"FuncInfo\" structure since IDAPRO resolved most of this SEH structure.\r\nwhen you try to load the sample in debugger and breakpoint on some API let say, you may encounter some\r\nexception error shown in figure below. This is also a good hint that it may use SEH technique. \r\nhttps://tccontre.blogspot.com/2021/02/gh0strat-anti-debugging-nested-seh-try.html\r\nPage 3 of 12\n\nfigure 4: exception during debugging\r\nby further checking its code using IDAPRO I notice that it uses nested SEH. yes a nested try{} catch{} exception\r\nhandler to decrypt its payload. at the entry point of the malware code you will notice right away the first exception\r\nhandler function registered to FS:0. Exception will be trigger by calling \"call    __CxxThrowException\" API. \r\nhttps://tccontre.blogspot.com/2021/02/gh0strat-anti-debugging-nested-seh-try.html\r\nPage 4 of 12\n\nfigure 5: first SEH in malware entrypoint\r\nehFuncInfo or the exception handler function registered in FS:0 contains some structure that may help us to figure\r\nout statically which exception handler function may be call upon the exception is trigger.\r\nI really recommend to read this great presentation of hexblog regarding the Exception and RTTI:\r\nhttps://www.hexblog.com/wp-content/uploads/2012/06/Recon-2012-Skochinsky-Compiler-Internals.pdf\r\nThe ehFuncInfo is a object structure that may lead you to the \"AddressOfHandler\" which is a address or a function\r\naddress that will handle the exception encounter of the current thread.\r\nIDAPRO really did a good job to give you some hint how to traverse that structure and lead you the said structure\r\nmember of HandlerType. FuncInfo structure contains several member so I will just focus on the member that\r\nhelps me to decrypt the payload.\r\nBelow is a simple structure starting from \"FuncInfo\" that may help you to look for the AddressOfHandler field\r\nmember of HandlerType structure. \r\nhttps://tccontre.blogspot.com/2021/02/gh0strat-anti-debugging-nested-seh-try.html\r\nPage 5 of 12\n\nfigure 6: Traversing AddressOfhandler\r\nThe figure 6 shows that FuncInfo structure contains TryBlockMap field. this field is another structure object that\r\ncontains HandlerArray field structure that holds the AddressOfHandler field. so to make use of this structure in\r\nour sample lets try to traverse the first SEH in malware entry point.\r\nhttps://tccontre.blogspot.com/2021/02/gh0strat-anti-debugging-nested-seh-try.html\r\nPage 6 of 12\n\nfigure 7: Traversing the AddressOfHandler of SEH in malware entry point\r\nWe saw that the possible Address that will handle the exception is in 0x40243d. It works in dynamically test I did\r\nwith x64dbg where I put break point on this address after the exception then press skip exception shift+f9.\r\nfigure 8: AddressOfHandler was triggered\r\nif we follow the call function 0x402200 pushing string address \"Shellex\" as a parameter. you will notice again that\r\nit use another SEH to execute piece of its code. Not like the first SEH, this SEH contains 9 tryblock and\r\nHandlerOfAddress like the figure below.\r\nhttps://tccontre.blogspot.com/2021/02/gh0strat-anti-debugging-nested-seh-try.html\r\nPage 7 of 12\n\nfigure 9: multiple try Block Map\r\nParsing ehFuncInfo structure Using Ida python:\r\nIn this case I decided to use IdaPython to parse all the FrameHandler ehFuncInfo structure to locate all\r\nAddressOfHandler field available for all tryBlockMap entries and add it as a code reference comment in its\r\nIDB. This approach help me to figure out where the decryption routine and learn multi line comment in idapython\r\n:).\r\nthe script is available here:\r\nhttps://tccontre.blogspot.com/2021/02/gh0strat-anti-debugging-nested-seh-try.html\r\nPage 8 of 12\n\nfigure 10A: before running the script\r\nfigure 10B: IDB after running the script\r\nhttps://tccontre.blogspot.com/2021/02/gh0strat-anti-debugging-nested-seh-try.html\r\nPage 9 of 12\n\nnow with this comment we can verify all possible AddressOfHandler in each tryBlockMap entry to locate the\r\ndecryption routine. Like the figure above, the first AddressOfHandler isa function waiting for the decryption key,\r\nsize of the encrypted payload and the address of the encrypted payload.\r\nfigure 11: decryption routine\r\nand once you decrypt the payload using this simple xor decryption routine. you can see right away some note\r\nworthy string of gh0strat like keylogging, creating services, regrun, download files, backdoor and etc.\r\nhttps://tccontre.blogspot.com/2021/02/gh0strat-anti-debugging-nested-seh-try.html\r\nPage 10 of 12\n\nfigure 12: strings upon decryption\r\nConclusion:\r\nIn this article we just focus on some basic internals of SEH frameHandler and how to look for all possible\r\nHandlerOfAddress that may executed upon the trigger of registered SEH. we also learned how IDAPRO did a\r\nreally good job in giving you all the needed structure for try block entries where you can use IDApython to make\r\nyour static analysis more easier. :)\r\nIOC:\r\nyara:\r\nimport \"pe\"\r\nrule gh0st_rat_loader {\r\n meta:\r\n author = \"tcontre\"\r\n description = \"detecting gh0strat_loader\"\r\n date = \"2021-02-22\"\r\nsha256 = \"70ac339c41eb7a3f868736f98afa311674da61ae12164042e44d6e641338ff1f\"\r\n strings:\r\n $mz = { 4d 5a }\r\n $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 }\r\n $str1 = \"Shellex\"\r\n $str2 = \"VirtualProtect\"\r\n \r\n \r\n condition:\r\n ($mz at 0) and $code and all of ($str*)\r\n }\r\n \r\nrule gh0st_rat_payload {\r\n meta:\r\n author = \"tcontre\"\r\n description = \"detecting gh0strat_payload in memory without MZ header in memory\"\r\n date = \"2021-02-22\"\r\nsha256 = \"edffd5fc8eb86e2b20dd44e0482b97f74666edc2ec52966be19a6fe43358a5db\"\r\n strings:\r\n $dos = \"DOS mode\"\r\nhttps://tccontre.blogspot.com/2021/02/gh0strat-anti-debugging-nested-seh-try.html\r\nPage 11 of 12\n\n$av_str1 = \"f-secure.exe\"\r\n $av_str2 = \"Mcshield.exe\"\r\n $av_str3 = \"Sunbelt\"\r\n $av_str4 = \"baiduSafeTray.exe\"\r\n \r\n $clsid = \"{4D36E972-E325-11CE-BFC1-08002BE10318}\"\r\n $s1 = \"[WIN]\"\r\n $s2 = \"[Print Screen]\"\r\n $s3 = \"Shellex\"\r\n $s4 = \"HARDWARE\\\\DESCRIPTION\\\\System\\\\CentralProcessor\\\\0\"\r\n $s5 = \"%s\\\\%d.bak\"\r\n \r\n condition:\r\n ($dos at 0x6c) and 2 of ($av_str*) and 4 of ($s*) and $clsid\r\n }\r\nReferences:\r\nhttps://www.hexblog.com/wp-content/uploads/2012/06/Recon-2012-Skochinsky-Compiler-Internals.pdf\r\nSource: https://tccontre.blogspot.com/2021/02/gh0strat-anti-debugging-nested-seh-try.html\r\nhttps://tccontre.blogspot.com/2021/02/gh0strat-anti-debugging-nested-seh-try.html\r\nPage 12 of 12",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"Malpedia"
	],
	"references": [
		"https://tccontre.blogspot.com/2021/02/gh0strat-anti-debugging-nested-seh-try.html"
	],
	"report_names": [
		"gh0strat-anti-debugging-nested-seh-try.html"
	],
	"threat_actors": [
		{
			"id": "d90307b6-14a9-4d0b-9156-89e453d6eb13",
			"created_at": "2022-10-25T16:07:23.773944Z",
			"updated_at": "2026-04-10T02:00:04.746188Z",
			"deleted_at": null,
			"main_name": "Lead",
			"aliases": [
				"Casper",
				"TG-3279"
			],
			"source_name": "ETDA:Lead",
			"tools": [
				"Agentemis",
				"BleDoor",
				"Cobalt Strike",
				"CobaltStrike",
				"RbDoor",
				"RibDoor",
				"Winnti",
				"cobeacon"
			],
			"source_id": "ETDA",
			"reports": null
		}
	],
	"ts_created_at": 1775434892,
	"ts_updated_at": 1775791271,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/dc049b1e012f71fb39aa3df9365350123b455256.pdf",
		"text": "https://archive.orkl.eu/dc049b1e012f71fb39aa3df9365350123b455256.txt",
		"img": "https://archive.orkl.eu/dc049b1e012f71fb39aa3df9365350123b455256.jpg"
	}
}