Giter Site home page Giter Site logo

Comments (8)

mavetek avatar mavetek commented on May 24, 2024 1

Hello, I re-opened this because I think there are few errors.
In the same method, isThreadInAlertableState() and IsThreadInAlertableState_WOW64

In

else if (ctx.Eip == m_WaitFunctionReturnAddress[4])
{
	return (stack_buffer[4] == TRUE);
}
// and in:
else if (ctx.Eip == m_WaitFunctionReturnAddress_WOW64[4])
{
	return (stack_buffer[4] == TRUE);
}

bAlertable in NtRemoveIoCompletionEx is the sixth argument

typedef struct _FILE_IO_COMPLETION_INFORMATION
{
  PVOID KeyContext;
  PVOID ApcContext;
  IO_STATUS_BLOCK IoStatusBlock;
} FILE_IO_COMPLETION_INFORMATION, * PFILE_IO_COMPLETION_INFORMATION;

extern "C" NTSTATUS NTAPI
NtRemoveIoCompletionEx(
  __in HANDLE IoCompletionHandle,
  __out_ecount(Count) PFILE_IO_COMPLETION_INFORMATION IoCompletionInformation,
  __in ULONG Count,
  __out PVOID NumEntriesRemoved,
  __in_opt PLARGE_INTEGER Timeout,
  __in BOOLEAN Alertable
);

I think it should be:

DWORD stackBuffer[7] = {0};
// ...
return (stackBuffer[6] == TRUE);

I tested it with the current code:

HANDLE hIoCompletion;
NTSTATUS status = NtCreateIoCompletion(&hIoCompletion, MAXIMUM_ALLOWED, nullptr, 0);
if (!NT_SUCCESS(status))
{
    err("Error NtCreateIoCompletion: %08X\n", status);
    return;
}

OVERLAPPED_ENTRY entry[1];
ULONG nEntries = 1;
ULONG removedEntries;
// This routine calls NtRemoveIoCompletionEx.
BOOL result = GetQueuedCompletionStatusEx(hIoCompletion,
                                            entry,
                                            nEntries,
                                            &removedEntries,
                                            INFINITE,
                                            TRUE);

To be fair, you never really reach this point, because when its on "wait", NtRemoveIoCompletionEx is on WrQueue

do
{
	KWAIT_REASON reason;
	THREAD_STATE state;
	if (!PI.GetThreadState(state, reason) || reason == KWAIT_REASON::WrQueue)
	{
		continue;
	}

	if (!PI.IsThreadWorkerThread() && (PI.IsThreadInAlertableState() || state == THREAD_STATE::Running))
	{
		ThreadID = PI.GetThreadId();
		break;
	}

} while (PI.NextThread());

With this one Im not sure but if I leave UINT_PTR as buffer type, I get something like 0xcccccc01 or 0xcccccc00. So I just changed it with a BYTE.

else if (ctx.Rip == m_WaitFunctionReturnAddress[4] && ctx.Rsp)
{
    UINT_PTR buffer = 0;
    if (ReadProcessMemory(m_hCurrentProcess, reinterpret_cast<void*>(ctx.Rsp + 0x30), &buffer, sizeof(buffer), nullptr))
    {
        return (buffer == TRUE);
    }
}

Last one, this one is really trivial, in GetProcAddressEx_WOW64 pe_header is initialized but never used.

from gh-injector-library.

Broihon avatar Broihon commented on May 24, 2024 1

Thanks, you're completely right about the the stack index being 6 and not 4. I must have thought the function was a __fastcall or something like that.
Will be fixed in the next version.

The x64 thingy one is weird though because when the argument is pushed on the stack or moved on the stack it should overwrite all 8 bytes and not just the lowest byte (which is why I used the UINT_PTR). But yeah, seems like using a byte-sized type is the way to go here.

Generally it seems like I didn't properly debug this. Probably because NtRemoveIoCompletionEx never occurs.
WrQueue threads usually are threadpool worker threads which also get filtered by the IsThreadWorkerThread check.

The pe_header thingy is probably from older variant of the function. Thanks.

Please let me know if you find more stupid stuff in my code. This project is much older than the repo and some older parts probably contain shitcode I wrote years ago and which I have forgotten about now.

from gh-injector-library.

Broihon avatar Broihon commented on May 24, 2024 1

I think I fixed everything in this update.
Feel free to open another issue if you find something. For now I'll close this one.
And also feel free to ask me if you have any questions.

from gh-injector-library.

Broihon avatar Broihon commented on May 24, 2024

Those are the correct registers for the bAlertable argument, yes. But when grabbing the context of the thread those don't work.
The thread currently is sleeping and the RIP is already set to the instruction after the syscall so I assume the kernel call somehow messes up r8/r9 which makes sense since those are volatile registers.
Luckily RSI seems to contain the same bool everytime those two functions are called. And since RSI is non volatile it doesn't get screwed up by the syscall.

Here's some really crappy code to demonstrate this. Just change the last argument in the WaitForMultipleObjectsEx call to verify this.
(Same works for SignalObjectAndWait)

#include <iostream>
#include <Windows.h>

DWORD __stdcall Thread(void * pArg)
{
	HANDLE hEvent = CreateEventA(nullptr, TRUE, FALSE, "");
	WaitForMultipleObjectsEx(1, &hEvent, TRUE, INFINITE, TRUE);
	
	return 0;
}


int main()
{
	HANDLE hThread = CreateThread(nullptr, 0, Thread, nullptr, NULL, nullptr);

	Sleep(250);
	
	CONTEXT ctx;
	ctx.ContextFlags = CONTEXT_ALL;
	GetThreadContext(hThread, &ctx);

	printf("rsi %d\n", ctx.Rsi);
	printf("r9  %d\n", ctx.R9);

	return 0;
}

from gh-injector-library.

mavetek avatar mavetek commented on May 24, 2024

Oh now its clear. I'm new to reversing and I'm learning a lot from this project, thank you.

from gh-injector-library.

mavetek avatar mavetek commented on May 24, 2024

Yea the UINT_PTR confused me too, I just checked where this happens:

cmp dword ptr [rsp+0C8h], 0
setne al
byte ptr [rsp+28h], al

I guess it make sense.
If you want to see the disassembly I made a screenshot of that part
debug_uint_ptr

You did very little errors for such a project.
I still didn't read the whole project, but there are parts that I'm legit impressed, I have no idea how you managed to know certain things, but I can see there is a lot of research into it. I hope to reach your experience one day, in the meantime Im learning a lot from this project and the least I can do is trying to help. Im still new in this field so I have to be careful, I don't want to waste your time with false calls, I have a decent background with programming but in reversing I'm a total newbie. Very nice job.

from gh-injector-library.

Broihon avatar Broihon commented on May 24, 2024

Thanks, it's just a lot of googling and trial and error to be honest. Oh, and obviously asking other poeple who might know a thing.
One person I've talked to a lot is Akaion/Dewera who also wrote a really nice C# mapping library:
https://github.com/Dewera/Lunar
I highly recommend checking it out in case you're interested.

Anyway, a new version of my library is in progress but will still take some time. Hopefully still in 2020 though.

from gh-injector-library.

mavetek avatar mavetek commented on May 24, 2024

I'll definitely check him out but after I learn how to hijack a thread (Im learning it from your project, now im trying to write it by myself) and how to do the different type of hooks, I read something about it but I need practice, thats the only way to check if I truly understand the subject, its taking much time because everytime I end up learning a bunch of correlated stuff. Im still in the steep phase of the learning curve, but its cool, im enjoying it.
It will be interesting to see which changes you will make in the new version.

from gh-injector-library.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.