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

ResumeThread causes crash when unfreezing, possibly due to unhandled SuspendThread error #52

Open
ethanporcaro opened this issue Jan 11, 2024 · 5 comments

Comments

@ethanporcaro
Copy link

Sorry if this isn't enough information, threading is not my strong suit. Please let me know.

I'll occasionally get access violation errors when using a midhook for an x64 program. This is happening when the threads are resumed.

 	ntdll.dll!NtQueryInformationThread()	Unknown
 	KernelBase.dll!GetThreadId()	Unknown
	BF2VR.dll!safetyhook::execute_while_frozen(const std::function<void __cdecl(void)> & run_fn, const std::function<void __cdecl(unsigned int,void *,_CONTEXT &)> & visit_fn) Line 139	C++
 	BF2VR.dll!safetyhook::InlineHook::e9_hook(const std::shared_ptr<safetyhook::Allocator> & allocator) Line 323	C++
 	BF2VR.dll!safetyhook::InlineHook::setup(const std::shared_ptr<safetyhook::Allocator> & allocator, unsigned char * target, unsigned char * destination) Line 191	C++
 	BF2VR.dll!safetyhook::InlineHook::create(const std::shared_ptr<safetyhook::Allocator> & allocator, void * target, void * destination) Line 147	C++
 	BF2VR.dll!safetyhook::InlineHook::create<unsigned char *,unsigned char *>(const std::shared_ptr<safetyhook::Allocator> & allocator, unsigned char * target, unsigned char * destination) Line 108	C++
 	BF2VR.dll!safetyhook::MidHook::setup(const std::shared_ptr<safetyhook::Allocator> & allocator, unsigned char * target, void(*)(safetyhook::Context64 &) destination) Line 110	C++
 	BF2VR.dll!safetyhook::MidHook::create(const std::shared_ptr<safetyhook::Allocator> & allocator, void * target, void(*)(safetyhook::Context64 &) destination) Line 56	C++
 	BF2VR.dll!safetyhook::MidHook::create(void * target, void(*)(safetyhook::Context64 &) destination) Line 48	C++
 	BF2VR.dll!safetyhook::create_mid(void * target, void(*)(safetyhook::Context64 &) destination) Line 13	C++
 	BF2VR.dll!BF2VR::BF2Service::Initialize() Line 209	C++
 	BF2VR.dll!BF2VR::MainThread(HINSTANCE__ * hModule) Line 108	C++
 	kernel32.dll!BaseThreadInitThunk()	Unknown
 	ntdll.dll!RtlUserThreadStart()	Unknown

I read up on GetThreadId and from what I understand, it shouldn't be possible to crash the program. It's showing an access violation at 0x0.

Please let me know what I need to send to help with this. Thanks.

@praydog
Copy link
Collaborator

praydog commented Jan 11, 2024

Try using this PR and see if your issue goes away #51

However that is still quite strange if GetThreadId is crashing, I haven't heard of this. Would need to look at a disassembled dump of the surrounding bytes in ntdll

@praydog
Copy link
Collaborator

praydog commented Jan 11, 2024

The only thing I can think of off the top of my head is that something in the TEB or PEB may be invalid for a short time, but still will need the surrounding bytes of where it crashed

@ethanporcaro
Copy link
Author

Well that was a fun 3 hours.

Turns out GetThreadId wasn't causing the crash, it just consistently happened after a previous ResumeThread call that caused the crash.

Looking at the freezer, I see const auto suspend_count = SuspendThread(thread);. There is a check if it is -1 (error) but it just continues. I ran GetLastError() and it is returning 5 which should mean access denied. I think this is barely handled and messes up the threads when resumed.

I'll check later but I need a break.

@ethanporcaro ethanporcaro changed the title GetThreadID memory access violation for e9_hook ResumeThread causes crash when unfreezing, possibly due to unhandled SuspendThread error Feb 21, 2024
@praydog
Copy link
Collaborator

praydog commented Feb 21, 2024

One thing I kind of had an issue with with the suspender was that it just goes through the entire thread list again with the same NtGetNextThread rather than keeping a list of previously suspended handles (or thread id's and using NtOpenThread) and just iterating over those. Because any thread could be destroyed or created in the process of iterating over existing ones.

Did you try out the trapping PR?

@ethanporcaro
Copy link
Author

ethanporcaro commented Feb 21, 2024 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants