2

The question seems pretty simple, but I can't achieve this simple thing in a reasonable time. I have a malware proceeding to deobfuscate a large amount of APIs in memory. Only the pointer to the functions is stored, not the name. I just wanted to quickly get a list of the API names using the trace feature when x64dbg sees the info from the register. ({a:register} gives me the symbol related to this pointer)

The problem is that the TraceInto is really too slow since it has to test every non-user instruction. I have just tried to TraceInto and launches the command "StepOut" when the base address isn't linked to user code. But this command stops the tracing. RunToParty, RunToUserCode stop the tracing as well. I could set some commands to restart the tracing, but I haven't found any options in the documentation to append logs to the log file. The provided log file is cleared each time the tracing starts.

Do you have some tricks to perform such common tasks, that is to say, TraceInto only in the usercode ?

4
  • Can you share the SHA256 of the file you're working on?
    – Utkonos
    Apr 24, 2022 at 4:57
  • Unfortunately I cannot because of a NDA. Nevertheless, the question is for general purpose. I think the whole thing could be usefull in several cases. Do you think the problem is specific to the analyzed data ?
    – HK47
    Apr 25, 2022 at 6:08
  • That is understandable. Do you have a similar file that you can point to or to a malware family? Or if that is sensitive, can you point to a different malware family that deobfuscates API names in a similar way? To answer your questions, it helps to be able to look at exactly what you're looking at.
    – Utkonos
    Apr 26, 2022 at 11:37
  • I think this is a pretty similar sample : bazaar.abuse.ch/sample/… You have to unpack. It just loads the unmapped PE in memory.
    – HK47
    May 4, 2022 at 21:45

1 Answer 1

1

Based on the following sample:

be7df9b222558c6b2afce6db5b20645bf394901f3d5ba27945d5497a367c8034

The unpacked Quakbot payload is this:

c85839f837d0312d9fb5440b16fa4fe3769df6d8f986dfaa0b5a28fb9ec80e19

I have identified the call to the function which resolves the API names that you're asking about at address 0x10031E22. To catch all the API names, just set a conditional breakpoint there (SHIFT-F2). In the Log Text field of the breakpoint configuration, put {a:eax}. Then in the Break Condition field, put 0. With the breakpoint set, click the Run button or hit F9. You then go look at the log tab, and the API names should all be listed there. This is much faster than trying to do a trace, and you end up with the same dataset. It looks like there are more locations where API names are resolved, so you may need to rinse and repeat this process a couple times for each location where the API names are resolved. You can set multiple breakpoints for all the locations. Here is the list of API names that I collected from this sample at the address above:

Breakpoint at 10031E22 set!

<kernel32.LoadLibraryA>
<kernel32.LoadLibraryW>
<kernel32.FreeLibrary>
<kernel32.GetProcAddress>
<kernel32.GetModuleHandleA>
<kernel32.CreateToolhelp32Snapshot>
<kernel32.Module32First>
<kernel32.Module32Next>
<kernel32.WriteProcessMemory>
<kernel32.OpenProcess>
<kernel32.VirtualFreeEx>
<kernel32.WaitForSingleObject>
<kernel32.CloseHandle>
<kernel32.LocalFree>
<kernel32.CreateProcessW>
<kernel32.ReadProcessMemory>
<kernel32.Process32First>
<kernel32.Process32Next>
<kernel32.Process32FirstW>
<kernel32.Process32NextW>
<kernel32.CreateProcessAsUserW>
<kernel32.VirtualAllocEx>
<kernel32.VirtualAlloc>
<kernel32.VirtualFree>
<kernel32.OpenThread>
<kernel32.Wow64DisableWow64FsRedirection>
<kernel32.Wow64EnableWow64FsRedirection>
<kernel32.GetVolumeInformationW>
<kernel32.IsWow64Process>
<kernel32.CreateThread>
<kernel32.CreateFileW>
<kernel32.CreateFileA>
<kernel32.FindClose>
<kernel32.GetFileAttributesW>
<kernel32.SetFilePointer>
<kernel32.WriteFile>
<kernel32.ReadFile>
<kernel32.CreateMutexA>
<kernel32.ReleaseMutex>
<kernel32.FindResourceA>
<kernel32.FindResourceW>
<kernel32.SizeofResource>
<kernel32.LoadResource>
<kernel32.GetTickCount64>
<kernel32.ExpandEnvironmentStringsW>
<kernel32.GetThreadContext>
<kernel32.SetLastError>
<kernel32.GetComputerNameW>
<kernel32.Sleep>
<kernel32.SleepEx>
<kernel32.OpenEventA>
<kernel32.SetEvent>
<kernel32.CreateEventA>
<kernel32.TerminateThread>
<kernel32.QueryFullProcessImageNameW>
<kernel32.CreateNamedPipeA>
<kernel32.ConnectNamedPipe>
<kernel32.GetLocalTime>
<kernel32.ExitProcess>
<kernel32.GetEnvironmentVariableW>
<kernel32.GetExitCodeThread>
<kernel32.GetFileSize>
<kernel32.VirtualProtect>
<kernel32.VirtualProtectEx>
<kernel32.InterlockedCompareExchange>
<kernel32.CreateRemoteThread>
<kernel32.SetEnvironmentVariableW>
<kernel32.ResumeThread>
<kernel32.TerminateProcess>
<ntdll.RtlAddVectoredExceptionHandler>
<kernel32.DeleteFileW>
<kernel32.CopyFileW>
<kernel32.AllocConsole>
<kernel32.SetConsoleCtrlHandler>
<kernel32.GetModuleFileNameW>
<kernel32.GetCurrentProcess>
<kernel32.CreatePipe>

Breakpoint

Cheers!

3
  • Thank you for taking the time to do this. I ended up to use exactly what you have described to obtain the several lists of API's. :) I should have explained the general method to "TraceInto user code" was the purpose. Since you have use the same circumventing/manuel technique, I infer what I want isn't implemented inside x64dbg. So I marked up your response, thank you !
    – HK47
    May 6, 2022 at 13:55
  • 1
    I understand what you're asking. I have made a small modification to the answer. If you set Break Condition to 0. The execution will not stop and wait for you to continue on that breakpoint. It will just keep executing. This I think is what you're looking for. You still get the output you seek on the Log tab. And you don't need to hit F9 over and over. Also, about trace: I don't know how to do what you want to do with trace. Performing trace on large amounts of code is too slow for it to be a reasonable solution.
    – Utkonos
    May 7, 2022 at 15:07
  • Thank you for the modification !
    – HK47
    May 9, 2022 at 8:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.