Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Recent capa version don't work with sample dumped from memory #2580

Open
Ana06 opened this issue Jan 29, 2025 · 10 comments
Open

Recent capa version don't work with sample dumped from memory #2580

Ana06 opened this issue Jan 29, 2025 · 10 comments
Labels
bug Something isn't working viv-bug

Comments

@Ana06
Copy link
Member

Ana06 commented Jan 29, 2025

Description

I have dumped the UPX packed sample a27afd3ec5b3f2e705347b2c39847fcd659e430396abd081109db0e7f96d1d3e from memory using pd64. capa 7.3-8.0 does not detect any capabilities in the dumped sample, while capa 7.0-7.2 does.

Image

I wonder why capa does not detect the capabilities of this sample in the newer versions and if we can fix it.

capa 7.3-8.0 does detect capabilities on the UPX unpacked version (unpacked using upx -d after renaming the sections).

Steps to Reproduce

  1. Execute a27afd3ec5b3f2e705347b2c39847fcd659e430396abd081109db0e7f96d1d3e
  2. Dump the executed process with pd64 -pid <PID>
  3. Run capa 7.3 and 7.2 on the dumped sample

Versions

capa 7.3-8.0 standalone tool.

@Ana06 Ana06 added the bug Something isn't working label Jan 29, 2025
@mike-hunhoff
Copy link
Collaborator

It appears that something broke when we upgraded Vivisect from version 1.1.1 to >= 1.2.0.

Vivisect 1.1.1:

$ python scripts/show-features.py dumped.exe_  | grep api
  insn: 0x401070: api(__set_app_type)
  insn: 0x4010C7: api(__set_app_type)
  insn: 0x40119E: api(__getmainargs)
  insn: 0x401212: api(Sleep)
  insn: 0x401284: api(SetUnhandledExceptionFilter)
  insn: 0x40134C: api(malloc)
  insn: 0x401374: api(strlen)
  insn: 0x401380: api(malloc)
  insn: 0x401398: api(memcpy)
  insn: 0x401406: api(_cexit)
  insn: 0x40144C: api(_amsg_exit)
  insn: 0x40146A: api(_initterm)
  insn: 0x401493: api(GetStartupInfoA)
  insn: 0x401493: api(GetStartupInfo)
  insn: 0x4014B4: api(_initterm)
  insn: 0x401559: api(GetModuleHandleA)
  insn: 0x401559: api(GetModuleHandle)
  insn: 0x40156E: api(GetProcAddress)
[...]
  insn: 0x402E02: api(RtlDeleteCriticalSection)
  insn: 0x402E37: api(RtlInitializeCriticalSection)
  insn: 0x402EFA: api(strlen)
  insn: 0x402F77: api(strncmp)
  insn: 0x401559: api(GetModuleHandleA)
  insn: 0x401559: api(GetModuleHandle)
  insn: 0x40156E: api(GetProcAddress)
  insn: 0x412712: api(VirtualProtect)
  insn: 0x412730: api(VirtualProtect)
$

Vivisect 1.2.1:

$ python scripts/show-features.py dumped.exe_  | grep api
  insn: 0x412712: api(VirtualProtect)
  insn: 0x412730: api(VirtualProtect)
$

I'm not sure of the issue source. It could be a change to Vivisect between 1.1.1 and 1.2.0 or something that we didn't change in capa and/or viv_utils to accommodate the Vivisect changes. Running show-features.py for the function 0x401635 tells us that capa isn't seeing a majority of the instructions/basic blocks when using Vivisect 1.2.1 versus Vivisect 1.1.1:

Vivisect 1.1.1:

$ python scripts/show-features.py -F 0x401635 dumped.exe_
global: global: format(pe)
global: global: os(windows)
global: global: arch(amd64)
func: 0x401635
 func: 0x401635: characteristic(calls to) -> 0x401C9C
 func: 0x401635: characteristic(calls to) -> 0x401C9C
 bb: 0x401635: basic block
  insn: 0x401635: mnemonic(push)
 [...]
  insn: 0x401696: mnemonic(call)
  insn: 0x401696: characteristic(indirect call)
 bb: 0x401698: basic block
  insn: 0x401698: mnemonic(nop)
  insn: 0x401699: mnemonic(add)
  insn: 0x40169D: mnemonic(pop)
  insn: 0x40169E: mnemonic(ret)
$

Vivisect 1.2.1:

$ python scripts/show-features.py -F 0x401635 dumped.exe_
global: global: format(pe)
global: global: os(windows)
global: global: arch(amd64)
func: 0x401635
 func: 0x401635: characteristic(calls to) -> 0x401C9C
 bb: 0x401635: basic block
  insn: 0x401635: mnemonic(push)
$ 

@williballenthin
Copy link
Collaborator

williballenthin commented Jan 30, 2025

PE generally looks ok, but imports aren't reconstructed:

Image

@williballenthin
Copy link
Collaborator

williballenthin commented Jan 30, 2025

the same number of functions are recovered using viv 1.1.1 and viv 1.2.1, but the older version recovers many more instruction features:

Image

@williballenthin
Copy link
Collaborator

the new version seems to be recovering only a single instruction from each function:

Image

@williballenthin
Copy link
Collaborator

there are lots of warnings during viv workspace creation, and the addresses seem to line up with functions/instructions above:

Image

the logging message is here:
https://github.com/vivisect/vivisect/blob/5531bdae6f6511028eb3692f410ee763c77356f0/vivisect/tools/graphutil.py#L522
but this code hasn't been touched in 5 years or so. So the bug is probably in a different routine.

@williballenthin

This comment has been minimized.

@williballenthin

This comment has been minimized.

@williballenthin

This comment has been minimized.

@williballenthin
Copy link
Collaborator

by manually bisecting the changes, here's the offending viv commit:

Image

Image

vivisect/vivisect@6d6a5d9

@williballenthin
Copy link
Collaborator

this was added in vivisect/vivisect#622

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working viv-bug
Projects
None yet
Development

No branches or pull requests

3 participants