microsoft / microsoft/Detours

Unexpected Behavior: DLL loading error when recursively calling a mix of 32-bit and 64-bit subprocesses

Open
#282 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug
Dominant language
C++
Stars
6.4k
Forks
1.2k
PR merge metrics
No merged PRs in 30d

Description

Bug Description

I used Detours to write a tool. When I used it to time itself, recursively calling a mix of 32-bit and 64-bit subprocesses, some internal calls of DetourCreateProcessWithDllExA to LoadNtHeaderFromProcess failed with error code 299 (0x12B), which is Only part of a ReadProcessMemory or WriteProcessMemory request was completed., causing failure of outer functions. When running as administrator, the problem persists.

Command-Line Test Case

Assuming that you have a 32-bit and 64-bit program named test32.exe and test64.exe, respectively, which calls another CPU-intensive program (python test.py) that can run for a few seconds. test.zip

git clone https://github.com/kevintsq/GetProcessCPUTimeOnWindows.git
cd GetProcessCPUTimeOnWindows/bin.X64
./time ./time test32.exe
./time ../bin.X86/time test32.exe
./time ../bin.X86/time test64.exe
cd ../bin.X86
./time ./time test64.exe
./time ../bin.X64/time test64.exe
./time ../bin.X64/time test32.exe

Expected Behavior

No matter how I mix calls to 32-bit and 64-bit subprocesses, the output of the call sequence in the above example should show almost the same timing results for the subprocess. That is, one run should output the time twice, and these two times should be almost the same. This is because, according to my timing logic, in the above recursive call example, the DLL for timing should be injected into test32.exe or test64.exe twice in succession.

But the result is that only one time is correct in some cases, and the other CPU time is almost zero, indicating that the DLL for timing is injected into test32.exe or test64.exe only once. I found that some internal calls of DetourCreateProcessWithDllExA to LoadNtHeaderFromProcess failed with error code 299 (0x12B), which is Only part of a ReadProcessMemory or WriteProcessMemory request was completed., causing failure of outer functions. So the logic of my timing should not be a problem.

Detours Version

I cloned it yesterday from the main branch.

Additional Context

Some of the above examples may experience more severe failure (time.exe may fail to start from time.exe because DetourCreateProcessWithDllExA will return an error in this case) if I build it using nmake DETOURS_CONFIG=Debug.
I'm using VS 2022 v17.5.4, cl 19.35.32217.1, link 14.35.32217.1.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reproducing the listed mixed 32-bit/64-bit command sequences and tracing DetourCreateProcessWithDllExA through LoadNtHeaderFromProcess, focusing on the reported error 299. Compare successful and failing recursive launches, including Debug builds. Done means the mixed-architecture cases inject the timing DLL twice and avoid the reported partial-memory-read failure.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
operating-systems, reverse-engineering
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.