RunDll Exporters

One of the most interesting classes of functions that are exported by DLLs are functions that use the RunDll interface (this archived article describes it).

Thanks to traditional (today kinda old-school) programming conventions, many coders name their exported functions compatible with the RunDll interface in a way that makes them easy to identify. Basically, they often include the reference to ‘rundll’ in a function name.

Knowing that, we can make an attempt to comb through many ‘good’ DLLs to discover a list of libraries where some of the APIs they export… follow this simple naming convention. Analysis of my small DLL repo gave me the results shown below.

Looking at these results I can immediately see that some of them are very familiar Windows API names (f.ex. Control_RunDLL variants), but there are many others that are mostly unknown. And many of libraries that export these functions come from other vendors than Microsoft, the exported APIs have almost no documentation and a minimalistic footprint online – basically, googling some of them brings very limited results.

I have a gut feeling that at least some of them are good lolbin potentials.

549  _InfEngUnInstallINFFile_RunDLL@16
485  InfEngUnInstallINFFile_RunDLL
426  RunDLLEntryW
353  RunDll32Interface
252  ShowHidPropPageRunDll32
252  BluetoothUpdateSendToRunDll32
195  DelNodeRunDLL32
167  RunDLL32EP
133  ShowHidPropPageRunDll32W
132  UninstADrvRunDll
114  Rundll_Dial
 62  RunDLLEntry
 62  Control_RunDLL
 60  SHHelpShortcuts_RunDLL
 60  PrintersGetCommand_RunDLL
 60  OpenAs_RunDLL
 58  SRS_InitializeEndpoints_Rundll32
 58  SRS_CleanupEndpoints_Rundll32
 58  SHHelpShortcuts_RunDLLW
 58  SHHelpShortcuts_RunDLLA
 58  PrintersGetCommand_RunDLLW
 58  PrintersGetCommand_RunDLLA
 58  OpenAs_RunDLLW
 58  OpenAs_RunDLLA
 58  Control_RunDLLW
 58  Control_RunDLLA
 54  RunDllDoPreInstall
 54  Control_FillCache_RunDLL
 52  Control_FillCache_RunDLLW
 52  Control_FillCache_RunDLLA
 50  BTINS_RunDll
 46  _RunDLLEntry@16
 41  ShellExec_RunDLLW
 41  ShellExec_RunDLLA
 41  ShellExec_RunDLL
 41  CplRunDll32
 41  Control_RunDLLAsUserW
 40  RunDll
 39  RunDllW
 38  SHCreateLocalServerRunDll
 38  Options_RunDLLW
 38  Options_RunDLLA
 38  Options_RunDLL
 38  AppCompat_RunDLLW
 32  Activate_RunDLL
 30  RunDll32ShimW
 30  HomeNetWizardRunDll
 25  TestRunDll
 24  ctCVWUtilityRunDLL32EP
 24  ctCVWIntroRunDLL32EP
 24  RundllUninstallA
 24  RundllInstallA
 23  ctCVWConsoleRunDLL32EP
 22  ctCVWParentalRunDLL32EP
 22  RunDllPromptForReboot
 20  SetupRunDll32Entry
 20  SelectSetupRunDll32Ex
 20  RunDllRegister
 19  UpgradePrinterRunDll32Ex
 18  RunDLL_InstallOEMDeviceEx
 18  RunDLL_InstallOEMDevice
 17  DelNodeRunDLL32W
 17  DelNodeRunDLL32A
 16  RunDLL_ExtractCabinetFile
 16  RunDLL32_UnregisterApplication
 16  RunDLL32_RegisterApplication
 16  RunDLL32_FilterRunOnceExRegistration
 15  RunDllEntryPoint
 13  SxsRunDllInstallAssemblyW
 13  SxsRunDllInstallAssembly
 12  IID_IShellRunDll
 11  usb_uninstall_service_np_rundll
 11  usb_install_service_np_rundll
 11  usb_install_driver_np_rundll
 11  TestPrint_RunDLLW
 11  RunDLL_InstallMultipleOEMDevicesEx
 11  @Jvjclutils@RunDll32Internal$qqruix17System@AnsiStringt2t2i
 11  @Jvjclutils@RunDLL32$qqrx17System@AnsiStringt1t1oi
 10  usb_touch_inf_file_np_rundll
  9  @Registryscan@TRegistryScan@HandleRundll32$qqr17System@AnsiStringo
  9  @PRunDLLCommand@saveGuts$xqr6RWFile
  9  @PRunDLLCommand@restoreGuts$qr6RWFile
  9  @PRunDLLCommand@newSpecies$xqv
  9  @PRunDLLCommand@myAtom
  9  @PRunDLLCommand@isA$xqv
  9  @PRunDLLCommand@copy$xqv
  9  @PRunDLLCommand@classIsA$qv
  9  @PRunDLLCommand@binaryStoreSize$xqv
  9  @PRunDLLCommand@UnExecute$qv
  9  @PRunDLLCommand@SetThirdParam$qrx9RWCString
  9  @PRunDLLCommand@SetSecondParam$qrx9RWCString
  9  @PRunDLLCommand@SetFunctionType$q12ERunDLLTypes
  9  @PRunDLLCommand@SetFunctionName$qrx9RWCString
  9  @PRunDLLCommand@SetFirstParam$qrx9RWCString
  9  @PRunDLLCommand@SetDLLName$qrx9RWCString
  9  @PRunDLLCommand@GetVersion$xqv
  9  @PRunDLLCommand@GetThirdParam$xqv
  9  @PRunDLLCommand@GetSecondParam$xqv
  9  @PRunDLLCommand@GetFunctionType$xqv
  9  @PRunDLLCommand@GetFunctionName$xqv
  9  @PRunDLLCommand@GetFirstParam$xqv
  9  @PRunDLLCommand@GetDLLReturnValue$xqv
  9  @PRunDLLCommand@GetDLLName$xqv
  9  @PRunDLLCommand@Execute$qv
  9  @PRunDLLCommand@$beql$xqrx11MPersistent
  9  @PRunDLLCommand@$bdtr$qv
  9  @PRunDLLCommand@$bctr$qv
  9  @PRunDLLCommand@$bctr$qrx14PRunDLLCommand
  9  @PRunDLLCommand@$basg$qrx14PRunDLLCommand
  8  _Java_com_sun_java_accessibility_AccessBridge_runDLL@8
  8  InstallSecurityPromptRunDllW
  8  DeviceProperties_RunDLLW
  8  DeviceProperties_RunDLLA
  7  DriverStoreRunDllW
  7  DeviceProblenWizard_RunDLLW
  7  DeviceProblenWizard_RunDLLA
  7  ?runDll@SV_HttpdAPI@@AAE_NPBD@Z
  6  extract_RunDLL
  6  WOW64Uninstall_RunDLLW
  6  UsersRunDll
  6  SxspRunDllDeleteDirectoryW
  6  SxspRunDllDeleteDirectory
  6  S3Disp_RunDll
  6  Rundll32RegisterServer
  6  RunDllProcW
  6  RunDllProcA
  6  RunDllEntry
  6  RunAsNewUser_RunDLLW
  6  PrepareDiscForBurnRunDllW
  6  LaunchMSHelp_RunDLLW
  6  AddNetPlaceRunDll
  6  @Jcldotnet@RunDll32ShimW$qqsxuixuipbxi
  5  RunDll_SetDefaultPrinter
  5  RunDll32Main
  5  PublishRunDll
  5  PassportWizardRunDll
  5  CscPolicyProcessing_RunDLLW
  5  CSCOptions_RunDLLW
  5  CSCOptions_RunDLLA
  5  CSCOptions_RunDLL
  4  update_start_rundll_old
  4  update_start_rundll
  4  uninstall_start_rundll_old
  4  uninstall_start_rundll
  4  rundll32_shellexec
  4  Wizard_RunDLL
  4  Rundll_EntryPoint
  4  DiskCopyRunDllW
  4  DiskCopyRunDll
  4  CI3_CreateShortcut_RUNDLL_32
  3  fnRunDll32
  3  _rundll32_shellexec@16
  3  WdipLaunchRunDLLUserHost
  3  Rundll32
  3  RunDll_UpdateDriver
  3  RunDll_Reenumerate
  3  RunDllHardwareTest
  3  RunDllA
  3  News_RunDLL
  3  NdfRunDllHelpTopic
  3  NdfRunDllDuplicateIPOffendingSystem
  3  NdfRunDllDuplicateIPDefendingSystem
  3  NdfRunDllDiagnoseWithAnswerFile
  3  NdfRunDllDiagnoseNetConnectionIncident
  3  NdfRunDllDiagnoseIncident
  3  Mail_RunDLL
  3  LogOffRunDLL
  3  Java_com_sun_java_accessibility_AccessBridge_runDLL
  3  CreateRegWizard_RunDll
  3  BoxedAppSDK_RunDll32_Callback
  2  rundll_analyze
  2  rundllIsAdmin
  2  _RunDll
  2  _RunDLLReport@16
  2  ShowRunDLLW
  2  ShowRunDLL
  2  ServiceRunDll
  2  RunDll32
  2  RunDLL_SaveImageFile
  2  RunDLL_RemoveDevice
  2  RunDLL_MountFileW
  2  RunDLL_MountFile
  2  RunDLL_DoCleanupW
  2  RunDLL_DoCleanupA
  2  RunDLLReport
  2  NotifyDevicesNeedRebootRunDllW
  2  ICRemoveByRundll
  2  ICInstallByRundll
  2  GetRunDllModule
  2  FromRunDll
  2  DllUnregisterServer_RunDll
  2  DllRegisterServer_RunDll
  2  DllIsRegisterServer_RunDll
  1  rundll_install_npq2f_srv2003
  1  rundll_install_npq2f
  1  rundll_install_ex
  1  rundll_install
  1  rundll_config
  1  dtuSerialRunDll
  1  dpuRunDllXML
  1  _RunDLL_SaveImageFile@16
  1  _RunDLL_RemoveDevice@16
  1  _RunDLL_MountFileW@16
  1  _RunDLL_MountFile@16
  1  UsersRunDllW
  1  Rundll32Call
  1  RunDllUnregisterMAPI
  1  RunDllRegisterMAPI
  1  RunDllInterfaceW
  1  RunDLLCommand
  1  RunDLL
  1  RegisterRunDll
  1  NetAccWizRunDll
  1  MigrateRunDll32
  1  ManageCardSpace_RunDll
  1  InstallReg_RunDLL
  1  ImportInformationCard_RunDllW
  1  ImportInformationCard_RunDllA

I don’t include sample hashes this time as I don’t want to make your life easier.

Da Li’L World of DLL Exports and Entry Points, Part 6

I love looking at clusters of files, because it’s the easiest way to find patterns. In the last part of this series I focused on Nullsoft installers (DLLs!) only, and today, I will use the very same idea to describe clusters of DLL families I have generated from a very large corpora of clean samples (collected over last decade, or so).

What makes a summary like this interesting?

Some malware families like to ’emulate’ real software. They imitate clean .exe and .dll files by copypasteing their lists of imports, exports, internal strings, but then adding an extra import or export here and there; some go as far as to integrate their malicious code with the existing source code. So, the compiled embedded malicious code occupies like 5-10% of the actual binary, and the rest is all nice and dandy code ‘borrowed’ from some open source project. Detecting a malicious code inside such binaries is not trivial, but one thing that sometimes gives the badness away is that extra export. So, this post is about these extra exports…

The most popular exports combo in my sampleset is this:

148199
DllCanUnloadNow
DllGetClassObject
DllRegisterServer
DllUnregisterServer

No surprises here, it’s your traditional COM library at work.

The next two are variants of the above, but including an extra export:

27741
DllCanUnloadNow
DllGetClassObject
DllInstall
DllRegisterServer
DllUnregisterServer

24647
DllCanUnloadNow
DllGetClassObject
DllMain
DllRegisterServer
DllUnregisterServer

Now you know where it’s heading…

When you analyze a DLL, and it includes all the export functions from the sets above, BUT then export some additional functions, these functions are definitely of interest. This doesn’t mean all DLLs that export these ‘default’ sets + something extra that I am highlighting as ‘functions of interest’ are malicious. It’s just an easy win to focus on these extra exported functions first, even if just to discover that a legitimate programmer of a legitimate DLL was overzealous in over-exporting functions…

Here’s an example of a legitimate set with these ‘extras’:

2019
DeferredDeleteW
DllCanUnloadNow
DllGetClassObject
DllInstall
DllRegisterServer
DllUnregisterServer
InstallPackagesManagedW
InstallPackagesW
ReinstallPackageW
ResumeAsyncW
ResumeW
UninstallPackageW

or

1464
DllCanUnloadNow
DllGetClassForm
DllGetClassInfo
DllGetClassObject
DllGetInterface

Secondly, many of traditional DLL exports are _not_ meant to be executed from the likes of rundll32.exe.

What does it mean?

These popular DLL Export combos give you a list of functions that, if seen being invoked via command line, are most likely an indicator of something ‘funny’ going on. This is because these functions are (normally) not designed to be rundll32-friendly and are meant to be accessed programmatically only. There are exceptions, of course…. f.ex. tailored DllInstall is sometimes invoked by legitimate software and via rundll32.exe, but the main message here is that if you see rundll32.exe executing one of the non-rundll32-exe friendly functions, you better start investigating…

Last, but not least — remember that DLLs exporting via ordinals is a thing too, so keep this in mind during your analysis….

So, what other ‘healthy’ combos we can see out there?

  • QT Plug-ins export these two functions:
1847
qt_plugin_instance
qt_plugin_query_metadata
1612
gegl_module_query
gegl_module_register
  • NVIDIA Stereo API DLLs:
1582
GetStereoApi

There are many other combos like this, but in today’s era of AI knowing-it-all, ask your nearest chatGPT for the full list, mine is most likely already quite obsolete 🙂