# Summary
Malware uses InnoSetup and hides the installer password in obfuscated, compiled PascalScript, but this article is not about this malware.
I abandoned all sanity and wrote an emulator for this arcane language to recover them.
This article is about the process of reverse engineering the runtime:
While IFPS has an open-source interpreter, I found it easier to recover the logic from existing code by assuming that it works.
If you found this because you are interested in Inno Setup stuff and IFPS: The emulator and archive parsing is open source and [implemented in BinaryRefinery](https://binref.github.io/lib/inno/index.html).
Feel free to file issues on GitHub for issues, questions, or feature requests.
Do you want to know more?
I have a Windows VM that can has an internet connection that acts as a tunnel into a VPN, and this VM is supposed to share this internet connection with the host. This works perfectly in principle: On that Windows VM, I have a network interface named
Outbound
which represents the VPN connection, and an interface named Gateway
which represents the connection that is shared with the host. I use Windows Internet Connection Sharing (ICS) to provide routing to the Gateway
interface via Outbound
. For reasons unknown to me, however, this sometimes just breaks and the only way to get it running again is to simply disable ICS on the Outbound
interface and re-enable it. Doing this through the UI every time became annoying, so I researched how to do it programmatically. There is [a great superuser answer](https://superuser.com/a/649183/222330) which provides _almost_ all the details you need, but not quite.
Do you want to know more?
When you write a lot of Python that is intended to mimic arithmetic that was taken from C or assembly code, one giant advantage of Python sometimes becomes a burden: The integers are arbitrary precision, and the "built-in" wrapping of fixed-width integer types is something that has to be added manually, sometimes a truly arduous process. I recently had a thought about how this can be done in a slightly less agonizing way. This is a prototype and might require some more extension in the future, but I am pretty happy with it already. The idea is to implement a decorator that will use Python's
ast
module to add a bitmask to each arithmetic operation that occurs in the code of a decorated function. Here's the code:
import ast
import functools
import inspect
def masked(mask: int):
'''
Convert arithmetic operations that occur within the decorated function body in such a way that
the result is reduced using the given bitmask. All additions, subtractions, multiplications,
left shifts, and taking powers is augmented by introducing a bitwise and with the given mask.
'''
def decorator(function):
code = inspect.getsource(function)
tree = ast.parse(code, mode='exec')
class Postprocessor(ast.NodeTransformer):
name = None
def visit_BinOp(self, node: ast.BinOp):
node = self.generic_visit(node)
if not isinstance(node.op, (ast.Add, ast.Mult, ast.Sub, ast.LShift, ast.Pow)):
return node
return ast.BinOp(node, ast.BitAnd(), ast.Constant(mask))
def visit_FunctionDef(self, node: ast.FunctionDef):
node = self.generic_visit(node)
if self.name is None:
node.name = self.name = F'__wrapped_{node.name}'
for k in range(len(node.decorator_list)):
if node.decorator_list[k].func.id == masked.__name__:
del node.decorator_list[:k + 1]
break
return node
pp = Postprocessor()
fixed = ast.fix_missing_locations(pp.visit(tree))
eval(compile(fixed, function.__code__.co_filename, 'exec'))
return functools.wraps(function)(eval(pp.name))
return decorator
With this decorator, you can now write:
@masked(0xFFFF)
def test(x: int) -> int:
return x * 0xBAAD
This will leave all code exactly as it is except for the binary operations involving addition, multiplication, subtraction, left shift, and computing powers - all of these are converted to having one additional bitwise and operation on top.
**Disclaimer:** If you are not running Windows on your host, you might not get anything out of this post. Sorry Tux.
I am convinced that the Windows Sandbox is one of the best virtualization solutions to do dynamic malware analysis (for Windows malware, at least). The reason is quite simple: Distinguishing a Windows 10 Sandbox instance from the actual underlying Windows 10 install should be very difficult for malware. Specifically if the host is running on HyperV with Guarded Host enabled, my current understanding is that there are little to no differences between the two, but they are neatly isolated from one another. The configuration options are limited, but you can easily cook up a config that launches a WindowsSandbox instance that has all the tools you need for some basic unpacking & dynamic analysis. This is what my malware analysis sandbox looks like at launch:
I have successfully executed a number of samples that evade execution in other virtualized environments. That's a far cry from rigorous testing, so take my praise with a grain of salt. Still, it might be worth a try, the setup is really easy. Do you want to see my config?

There are two central problems that I faced with Slack:
1. Slack feels like I am developing in Eclipse, in a Windows VM, on an old Linux laptop. Where does all the bloat come from? It can't even have more than one channel open at a time!
2. In some cases, Slack can [force you to log out][SlackTimeout] after 12 hours, say. I understand why you would check that box as an IT admin, but I will show you that Slack is currently not enforcing this policy, and so I'd prefer to not be subject to it. 😼
## Good Slack Clients
The first problem is rather easy to solve, you simply use an alternative client. There are three options I am aware of:
- Using [WeeChat][] with the [WeeSlack][] plugin. I also recommend the [WeeEdit][] plugin to post multi line messages, especially for those code blocks. Finally, I use [WeeAutosort][] because the list of slack channels in WeeChat is a little confusing otherwise. This client is certainly your best option if your top priority is to go open source, to get it for free, or to use it on the command line. And it is a really good way to use Slack, too. I like it very much.
- You can use [Pidgin][] with the [slack-libpurple][SlackLibPurple] plugin. Unfortunately, I have to say that this works rather poorly and I mention it here only to be complete. I thoroughly recommend WeeChat if you are absolutely not willing to use a commercial and closed source program; it is better to use WeeChat with [WeeSlack][] in a terminal for Slack than to use the Pidgin plugin.
- If you are willing to pay $20 for your happiness, you should buy [Ripcord][] (Win/Linux/Mac supported). Even though it is in Alpha, it is the best Slack (and Discord!) client I have used. It supports Slack features in a more natural way because it is built specifically to do so, where in WeeChat some things may be awkward (inline images, navigating threads, etc). It is fast, has a low memory footprint, feels snappy, and gives you tabs for channels, DM's and threads. It is my weapon of choice.
[AndroidEmulator]: https://developer.android.com/studio/run/emulator
[AndroidEmulatorNetworking]: https://developer.android.com/studio/run/emulator-networking
[Ripcord]: https://cancel.fm/ripcord/
[MITMProxy]: https://mitmproxy.org/
[Pidgin]: https://pidgin.im/
[HAR]: https://en.wikipedia.org/wiki/HAR_(file_format)
[SlackLibPurple]: https://github.com/dylex/slack-libpurple
[WeeChat]: https://weechat.org/
[WeeSlack]: https://github.com/wee-slack/wee-slack
[WeeSlackSecure]: https://github.com/wee-slack/wee-slack#4-add-your-slack-api-keys
[SlackTimeout]: https://slack.com/intl/en-de/help/articles/115005223763-Manage-session-duration-?eu_nc=1
[SlackAPI]: https://api.slack.com/web
[SlackOverflow]: https://stackoverflow.com/questions/11012976/how-do-i-get-the-apk-of-an-installed-app-without-root-access
[NougatChanges]: https://android-developers.googleblog.com/2016/07/changes-to-trusted-certificate.html
[WeeEdit]: https://raw.githubusercontent.com/keith/edit-weechat/master/edit.py
[WeeAutosort]: https://raw.githubusercontent.com/de-vri-es/weechat-autosort/master/autosort.py
[WeeOTR]: https://raw.githubusercontent.com/mmb/weechat-otr/master/weechat_otr.py
## Loot Slack Tokens from Mobile
Now if you want to come along and get around periodic logouts in Slack with me, we'll have a bit of work to do.
I have spent some time reverse engineering Delphi binaries with IDA & HexRays at work, but IDA tends to make a few mistakes and I wrote a few scripts to fix them. Then [Ghidra](https://ghidra-sre.org/) came along and I was very curious to know how it would fare against some of the Delphi malware that I know and ~~loathe~~ love. I'd say it does about as bad as IDA, and so I went on a journey to rewrite my scripts from work as Ghidra scripts. TL/DR; [The scripts are on GitHub](https://github.com/huettenhain/dhrake/). But would you like to know **more**?
A while back [I blawgd about how to get the MSDN library for offline use](https://blag.nullteilerfrei.de/2017/12/21/get-the-msdn-library-for-offline-use/). However, the Help Viewer has its problems. I won't list all of its problems, but it was certainly a bad candidate to integrate Win32 API documentation support to Ghidra. There is [a pretty neat project by Laurence Jackson](http://laurencejackson.com/win32/), but I think I just found something a little better even: Microsoft provides [a download of the MSDN Library for Visual Studio 2008 SP1, stand-alone, offline, as an ISO](https://www.microsoft.com/en-us/download/details.aspx?displaylang=en&id=20955) - smell this, Help Viewer:
So this is nice, but the main point of this exercise was to integrate this into Ghidra. If that's something you care about, read on.

Do you ... analyze a lot of malware? Dynamically, too? Or do you just want to launch suspended processes? Well either way, although this is really easy to do, my intense web research did not yield satisfactory results. So here you go, this will just take the entire command line that is passed to it and execute it as a new, suspended process:
#include <Windows.h>
#include <Shlwapi.h>
BOOL ChrIsWhiteSpace(WCHAR x) {
return x == 32 || (x >= 9 && x <= 13);
}
int WinMainCRTStartup() {
int ArgCount = 0;
WCHAR* CommandLine = GetCommandLineW();
WCHAR** ArgList = CommandLineToArgvW(CommandLine, &ArgCount);
if (ArgList && ArgCount > 1) {
WCHAR* PtrRest = StrStrW(CommandLine, ArgList[1]);
if (PtrRest) {
STARTUPINFOW StartupInfo;
PROCESS_INFORMATION ProcessInfo;
while (!ChrIsWhiteSpace(*PtrRest))
PtrRest--;
GetStartupInfoW(&StartupInfo);
CreateProcessW(
NULL,
++PtrRest,
NULL,
NULL,
FALSE,
CREATE_SUSPENDED | INHERIT_PARENT_AFFINITY | DETACHED_PROCESS | CREATE_DEFAULT_ERROR_MODE,
NULL,
NULL,
&StartupInfo,
&ProcessInfo
);
CloseHandle(ProcessInfo.hProcess);
CloseHandle(ProcessInfo.hThread);
}
LocalFree(ArgList);
}
ExitProcess(0);
}
Do you want the Base64 encoded binary?
When I open up a file in IDA Pro, I usually want the HexRays decompiler panel to the right of the disassembly. It just so happens that I open up a lot of files in IDA Pro and I have to rearrange the panels every time. Now I finally sat down and wrote a little Python plugin that will rearrange the panels just the way I like them. You may have similar problems and may find it useful. You should be able (with only a small amount of pain) to modify the script according to your own preferred layout:
import idaapi
def runonce(function):
"""
A decorator which makes a function run only once.
"""
function._first_run = True
def wrapper(*args, **kwargs):
if function._first_run:
function._first_run = False
return function(*args, **kwargs)
return wrapper
@runonce
def position_pseudocode():
idaapi.set_dock_pos('Pseudocode-A', None, idaapi.DP_RIGHT)
idaapi.set_dock_pos('Graph overview', 'Output window', idaapi.DP_TAB)
idaapi.set_dock_pos('Functions window', 'Output window', idaapi.DP_TAB)
class PseudoCodeTabRight(idaapi.plugin_t):
flags = idaapi.PLUGIN_HIDE
comment = 'Opens the PseudoCode tab in a spearate pane to the right.'
help = 'The plugin triggers automatically when the decompiler is engaged for the first time.'
wanted_name = 'PseudoCodeTabRight'
wanted_hotkey = ''
def init(self):
def hexrays_event_callback(event, *args):
if event == idaapi.hxe_open_pseudocode:
position_pseudocode()
return 0
if not idaapi.install_hexrays_callback(hexrays_event_callback):
return idaapi.PLUGIN_SKIP
return idaapi.PLUGIN_KEEP
def run(self, arg=0):
pass
def term(self):
pass
def PLUGIN_ENTRY():
return PseudoCodeTabRight()
I have finally solved an annoying problem with my Windows 10 setup which was sortof hard to Google, so I am sharing. For quite some time, the computer had refused to go to sleep when it was not running on battery. Instead of going to sleep when instructed to, it would simply turn off the screen and mute the volume while continuing to *actually not sleep*. Moving the mouse a tiny bit would swiftly end the charade. In a recent fit of rage I decided to inspect the event log, and behold, there were some Kernel Power events that said:
> _The system is entering Away Mode._
Which is entirely _not_ what I wanted when I told it to go to sleep. However, there was no option _anywhere_ in the power settings to be found that turned off this _"Away Mode"_. Well, the option actually does exist, but for some reason it is not visible unless you set the
Attributes
value to 2
in the following, easily memorable registry key:
HKLM\SYSTEM\CurrentControlSet\Control\Power\PowerSettings\238C9FA8-0AAD-41ED-83F4-97BE242C8F20\25DFA149-5DD1-4736-B5AB-E8A37B5B8187
Armed with this registry tweak, you can go back to the _"advanced"_ power settings, aka:
rundll32 shell32.dll,Control_RunDLL PowerCfg.cpl @0,/editplan:
Navigate to Sleep
and there should be an option that says Allow Away Mode Policy
or something similar. And that policy should be set to no, not even when plugged in, never, just sleep, for crying out loud, why does this even exist.
As I [have hinted at before](/2017/09/20/just-some-friendly-advice/), the [PyCrypto library](https://www.dlitz.net/software/pycrypto/) [seems to be dead](https://github.com/dlitz/pycrypto/issues/173). The [PyCryptodome](https://www.pycryptodome.org/en/latest/) library is a fork that is promising because it is maintained and works in Python 3, but they have a bit of a finger-wagging attitude which sometimes means that you have to fight the library a bit:
>>> from Crypto.Cipher import ARC4
>>> cipher = ARC4.new(B'funk')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Python37\lib\site-packages\Crypto\Cipher\ARC4.py", line 132, in new
return ARC4Cipher(key, *args, **kwargs)
File "C:\Python37\lib\site-packages\Crypto\Cipher\ARC4.py", line 57, in __init__
len(key))
ValueError: Incorrect ARC4 key length (4 bytes)
>>> ARC4.key_size = range(1,257)
>>> ARC4.new(B'funk').decrypt( ARC4.new(B'funk').encrypt( B'Hello World' ))
b'Hello World'
They certainly mean well, but the library is no place to impose security standards, in my opinion. In malware research for example, we often have to verbatim copy the appalling use of certain ciphers, like ARC4 with a 4-byte key. It happens all the time!
I have been particularly struggling with [the removal of the XOR cipher](https://pycryptodome.readthedocs.io/en/latest/src/vs_pycrypto.html). The XOR implementation of PyCrypto was very fast, and in this article I will both benchmark how fast exactly it was and give you a drop-in replacement which degrades gracefully based on your options.
Do you want to know more?