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

system will be crash when calling NtControlTrace #7

Open
xets007 opened this issue Jul 25, 2019 · 36 comments
Open

system will be crash when calling NtControlTrace #7

xets007 opened this issue Jul 25, 2019 · 36 comments

Comments

@xets007
Copy link

xets007 commented Jul 25, 2019

No description provided.

@BerkanYildiz
Copy link
Contributor

BerkanYildiz commented Jul 25, 2019

Need more informations about the issue.

  • What OS are you on ? (Vista, 7, 10, ...)
  • What build are you on ? (1709, 1809, ...)
  • Do you have any anti-virus ?
  • Did you use the raw project on github without edits ? Or did you include the library in your own project ?
  • What do you mean by « crash » ? Does it BSOD ? What is the error code ?

@xets007
Copy link
Author

xets007 commented Jul 25, 2019

1、in function "ImgGetBaseAddress", you must call ZwQuerySystemInformation two times to get moduleinfomation, but you forgot to do it. Buffer memory is empty.
2、in my computer, ntosklnr.exe did not export the ZwControlTrace function, but only NtControlTrace. so i must rename the function from ZwXX To NtXX。
3、when i call NtControlTrace, My system BOSD.

my computer is win 7, x64, build 7601,dont have anit-virus!

The code I downloaded from GitHub can be compiled and passed, but it can't be loaded and run.
From the point of view of code details, it is possible that some of the details of this code have been lost.
If you have the complete code project, please send me a copy. Thank you.

@niallnsec
Copy link

niallnsec commented Jul 25, 2019

I saw the same thing. Did a bit of debugging trying to adjust the data passed to NtControlTrace, but no success. I personally did not post an issue as I have not had time to properly debug it to see whats going on, but I do have the following details which may help compliment the details provided by @xets007 (assuming we are seeing the same issue)

BSOD: ATTEMPTED_WRITE_TO_READONLY_MEMORY
BugCheck BE, {fffff880038b5260, 870be021, fffff88002f5f410, b}

OS: Windows 7 7601 x64 (7601.24475.amd64fre.win7sp1_ldr.190516-0600)

Stack:

fffff880`02f5eb48 fffff800`027a96d2 : fffff880`038b5260 fffffa83`00101660 00000000`00000065 fffff800`026c63c8 : nt!DbgBreakPointWithStatus
fffff880`02f5eb50 fffff800`027aa4c2 : fffff880`00000003 00000000`00000000 fffff800`026fe150 00000000`000000be : nt!KiBugCheckDebugBreak+0x12
fffff880`02f5ebb0 fffff800`026eeba4 : fffffa83`0439b950 00000000`00000002 fffff800`0286a630 00000000`00000002 : nt!KeBugCheck2+0x722
fffff880`02f5f280 fffff800`027c7d53 : 00000000`000000be fffff880`038b5260 00000000`870be021 fffff880`02f5f410 : nt!KeBugCheckEx+0x104
fffff880`02f5f2c0 fffff800`026fab96 : 00000000`00000001 fffff880`038b5260 00000000`00000000 00000000`0000003c : nt!MmAccessFault+0x1c13
fffff880`02f5f410 fffff800`026dcc8d : fffff800`026b59df 00000000`00000010 fffff800`029be6f0 00000000`00000010 : nt!KiPageFault+0x356
fffff880`02f5f5a8 fffff800`026b59df : 00000000`00000010 fffff800`029be6f0 00000000`00000010 00000000`00010202 : nt!memcpy+0xbd
fffff880`02f5f5b0 fffff800`0291536b : fffff8a0`00636000 fffffa83`02fd9040 00000000`00000000 fffff800`02af7e70 : nt!RtlCopyUnicodeString+0x3f
fffff880`02f5f5e0 fffff800`02af8697 : 00000000`00000000 00000000`10000480 fffffa83`02fd9040 00000000`00000400 : nt!EtwpGetLoggerInfoFromContext+0x19f
fffff880`02f5f630 fffff800`02b3212c : 00000000`00000000 fffffa83`02fd9040 fffffa83`0360a000 fffff880`038b60d0 : nt!EtwpUpdateTrace+0x477
fffff880`02f5f6b0 fffff880`038b38a2 : fffffa83`02f69000 fffffa83`02f69000 fffff880`00001000 fffffa83`0360a000 : nt!NtTraceControl+0x25c
fffff880`02f5f720 fffff880`038b3360 : fffff880`00000001 00000000`00000000 fffff880`038b5170 00000000`00000000 : kinfinityhook!IfhpModifyTraceSettings+0x222 [k:\src\infinityhook\libinfinityhook\infinityhook.cpp @ 479] 
fffff880`02f5f790 fffff880`038b32b7 : fffff880`038b31f0 fffff980`1664efd0 fffff880`038b5060 00000000`00000000 : kinfinityhook!IfhInitialize+0x50 [k:\src\infinityhook\libinfinityhook\infinityhook.cpp @ 125] 
fffff880`02f5f7d0 fffff880`038b9020 : fffffa83`04e18970 fffffa83`02f69000 fffffa83`00000002 fffff880`02f5f9c0 : kinfinityhook!DriverEntry+0x97 [k:\src\infinityhook\kinfinityhook\entry.cpp @ 62] 
fffff880`02f5f830 fffff800`02a97e56 : fffffa83`04e18970 ffffffff`80000910 fffff980`1664efd0 00000000`00000001 : kinfinityhook!GsDriverEntry+0x20 [minkernel\tools\gs_support\kmode\gs_support.c @ 117] 
fffff880`02f5f860 fffff800`02a98255 : 00000000`00000010 00000000`00000000 00000000`00000010 00000000`00010206 : nt!IopLoadDriver+0xa06
fffff880`02f5fb30 fffff800`026a6bed : fffff800`00000000 ffffffff`80000910 fffff800`02a98200 fffff800`0286b7f8 : nt!IopLoadUnloadDriver+0x55
fffff880`02f5fb70 fffff800`0299ce40 : 00000000`00000000 fffff800`0283f180 00000000`00000080 00000000`00000001 : nt!ExpWorkerThread+0x111
fffff880`02f5fc00 fffff800`026f4aa6 : fffff800`0283f180 fffffa83`00101660 fffffa83`00101b50 00000000`00000000 : nt!PspSystemThreadStartup+0x194
fffff880`02f5fc40 00000000`00000000 : fffff880`02f60000 fffff880`02f5a000 fffff880`02f5ed30 00000000`00000000 : nt!KiStartSystemThread+0x16

I am assuming from my limited testing and looking at the implementation of ZwControlTrace that it is probably not as simple as replacing the Zw version for the Nt version on Windows 7.

The above info comes from using the packaged project. I did make some changes so that the offsets would be correct for Windows 7 when walking the stack, but all the code I modified seems to come after this crash occurs and so I don't think it is related.

The machine it is being tested on is a VM running inside Hyper-V on a Windows 10 host (1903). It is fully patched and has no anti-virus. It is pretty much a clean install.

@BerkanYildiz
Copy link
Contributor

BerkanYildiz commented Jul 25, 2019

With the stack trace and given bug check, we can deduce that when EtwpGetLoggerInfoFromContext attempts to run RtlCopyUnicodeString, it tries to copy the string to a read-only memory region.

The address of that read-only memory region (0xfffff880038b5260) is very very close to the driver's one (around 0xfffff880038b3360 for IfhpModifyTraceSettings), so I suppose it's the data section of your driver module.

The only UNICODE_STRING allocated by this project that I can see is the ProviderName. Can you try allocating the provider name yourself and see if it still crashes ?

Property->ProviderName = RTL_CONSTANT_STRING(L"Circular Kernel Context Logger");

Something like :

PVOID Buffer = ExAllocatePool(NonPagedPool, 128);

UNICODE_STRING ProviderName = { };
ProviderName.Buffer = (PWCH) Buffer;
ProviderName.Length = sizeof(L"Circular Kernel Context Logger");
ProviderName.MaximumLength = 128;

RtlCopyMemory(Buffer, L"Circular Kernel Context Logger", (SIZE_T) ProviderName.Length);

Property->ProviderName = ProviderName;

// ..
// This code is for debugging purpose,
// use 'RtlInitUnicodeString(&ProviderName, L"Circular Kernel Context Logger")' instead.
// 
// Don't forget to ExFreePool if you use the code I've posted.

@niallnsec
Copy link

niallnsec commented Jul 25, 2019

So I allocated the string manually, code was almost exactly the same as yours above except I used a temp UNICODE_STRING to store the data.

UNICODE_STRING pnameTmp = RTL_CONSTANT_STRING(L"Circular Kernel Context Logger");
PWCHAR pname = (PWCHAR)ExAllocatePool(NonPagedPool, (SIZE_T)(pnameTmp.Length));

RtlCopyMemory(pname, pnameTmp.Buffer, pnameTmp.Length);

Property->ProviderName.Buffer = pname;

Doing so did indeed fix the crash! Thank you very much. I do seem to have run into other problems though.

I was working on the version of the source from the original commit, it failed inside of MmSearchMemory (not a bug check, it just couldn't find what it was looking for). As a test, I downloaded the latest version of the code with the various bugfixes from the past few days to make sure I hadn't broken something. Surprisingly, doing so resulted in a new bugcheck inside of ImgGetBaseAddress.

The bugcheck was PAGE_FAULT_IN_NONPAGED_AREA (0xFFFFFA8306F1F018,0x0000000000000000,0xFFFFF88003898A92,0x0000000000000000)

The exception occured here:

return ModuleInformation->ImageBase;

Looks like it is due to freeing that buffer immediately above.

I made the following change which seems to work:

PVOID ImageBase = ModuleInformation->ImageBase;

//
// Free the buffer. Thanks to @tandasat for catching my 
// silly mistake.
//
ExFreePool(Buffer);

return ImageBase;

@BerkanYildiz
Copy link
Contributor

BerkanYildiz commented Jul 25, 2019

Correct, one of the collaborator made a "patch" without actually testing it :p (Hi @nmulasmajic )
I requested the change in a PR #8 .

@niallnsec
Copy link

niallnsec commented Jul 25, 2019

Cool :) Out of curiosity, in the source there is a comment regarding the signature for EtwpDebuggerData stating that it should be the same on Windows 7+. I was wondering if you (or anyone else) had got it working for Windows 7 before? It does not seem to locate the pattern in my tests so far.

Currently, I am seeing IfhpResolveSymbols fail in the second search phase. It is not able to get the section base address for .rdata here:

SectionBase = ImgGetImageSection(NtBaseAddress, ".rdata", &SizeOfSection);

@niallnsec
Copy link

Still investigating, but it appears as it the routine does not come across the .rdata section at all. I added a debug print to the search function to note the names:

Section Name: .text
Section Name: KVASCODE
Section Name: INITKDBG
Section Name: POOLMI
Section Name: POOLCODE
Section Name: ALMOSTRO
Section Name: .data
Section Name: .pdata
Section Name: ALMOSTRO
Section Name: SPINLOCK
Section Name: PAGELK
Section Name: PAGE
Section Name: PAGEKD
Section Name: PAGEVRFY
Section Name: PAGEHDLS
Section Name: PAGEBGFX
Section Name: PAGEVRFB
Section Name: .edata
Section Name: PAGEDATA
Section Name: PAGEVRFC
Section Name: PAGEVRFD
Section Name: INIT
Section Name: .rsrc
Section Name: .reloc

This seemed odd, so I took a look at ntoskrnl.exe and it turns out that on Windows 7 there is no .rdata section. So I am not entirely sure what @ivanpos2015 was referring to in their issue. The only difference I can think of is that they specifically mentioned build 7600 but I am testing on 7601. I believe the difference there is whether or not SP1 is installed but I might be wrong.

@Ch40zz
Copy link

Ch40zz commented Jul 25, 2019

Just open ntoskrnl in ida and look for the pattern.
Its located in .text for latest windows 7 kernel:

.text:00000001400057B0 EtwpDebuggerData dq 0E00C3804082C0018h, 60041078000000B8h
.text:00000001400057B0                                         ; DATA XREF: .data:00000001401E8450↓o
.text:00000001400057C0                 dq offset WmipLoggerContext

@niallnsec
Copy link

Thanks @Ch40zz I was doing a search too, didn't expect to see it in the .text section :) Its curious that it got moved like that

@niallnsec
Copy link

niallnsec commented Jul 25, 2019

So I made the following addition and now it loads without issue for me. Once the offsets are fixed for Windows 7 it works perfectly! Thanks for the assistance @BerkanYildiz and @Ch40zz

SectionBase = ImgGetImageSection(NtBaseAddress, ".rdata", &SizeOfSection);
if (!SectionBase)
{
	SectionBase = ImgGetImageSection(NtBaseAddress, ".text", &SizeOfSection);
	if (!SectionBase)
	{
		return FALSE;
	}
}

I am happy to post the offsets for Windows 7 too, but I get the impression they were intentionally not included?

@BerkanYildiz
Copy link
Contributor

Happy you got it working, yay ! 🎉
For your question, it's anyhow you want. You can do a pull request if you wish to.

@nmulasmajic
Copy link
Collaborator

Correct, one of the collaborator made a "patch" without actually testing it :p (Hi @nmulasmajic )
I requested the change in a PR #8 .

Fixed it. My fault for not testing, sorry.

Just open ntoskrnl in ida and look for the pattern.
Its located in .text for latest windows 7 kernel:

.text:00000001400057B0 EtwpDebuggerData dq 0E00C3804082C0018h, 60041078000000B8h
.text:00000001400057B0                                         ; DATA XREF: .data:00000001401E8450↓o
.text:00000001400057C0                 dq offset WmipLoggerContext

7601 (6.1.7601.17514) has EtwpDebuggerData in .rdata. Just checked on my end. What version of the 7 kernel is that?

@Ch40zz
Copy link

Ch40zz commented Jul 25, 2019

7601 (6.1.7601.17514) has EtwpDebuggerData in .rdata. Just checked on my end. What version of the 7 kernel is that?

6.1.7601.24024 (win7sp1_ldr.180112-0600)

@xets007
Copy link
Author

xets007 commented Jul 26, 2019

With the stack trace and given bug check, we can deduce that when EtwpGetLoggerInfoFromContext attempts to run RtlCopyUnicodeString, it tries to copy the string to a read-only memory region.

The address of that read-only memory region (0xfffff880038b5260) is very very close to the driver's one (around 0xfffff880038b3360 for IfhpModifyTraceSettings), so I suppose it's the data section of your driver module.

The only UNICODE_STRING allocated by this project that I can see is the ProviderName. Can you try allocating the provider name yourself and see if it still crashes ?

Property->ProviderName = RTL_CONSTANT_STRING(L"Circular Kernel Context Logger");

Something like :

PVOID Buffer = ExAllocatePool(NonPagedPool, 64 * 2);

UNICODE_STRING ProviderName = { };
ProviderName.Buffer = (PWCH) Buffer;
ProviderName.Length = sizeof(L"Circular Kernel Context Logger") / 2;
ProviderName.MaximumLength = 64;

RtlCopyMemory(Buffer, L"Circular Kernel Context Logger", (SIZE_T) ProviderName.Length);

Property->ProviderName = ProviderName;

// ..
// This code is for debugging purpose, mess with RtlInitUnicodeString instead.
// Don't forget to ExFreePool.

the returned value of NtTraceControl is 0xC0000035
[-] infinityhook: Failed to initialize with status: 0xc0000035.
无标题

@BerkanYildiz
Copy link
Contributor

BerkanYildiz commented Jul 26, 2019

I don't think you did it correctly.
The error values you are getting means that the ETW thingy exists, but your code fails to actually retrieve it, so you're trying to initialize it but it fails again because as stated previously, it does exist, you can't recreate it again.
Make you sure didn't edit anything incorrectly :^)

@SpriteOvO
Copy link

SpriteOvO commented Jul 27, 2019

[+] infinityhook: Loaded.
[-] infinityhook: Failed to initialize with status: 0xc0000035.

I got the same failure code as @xets007.

The problem has been solved. It is because of my own stupidity. Thanks to @nmulasmajic for your answers.

@nmulasmajic
Copy link
Collaborator

nmulasmajic commented Jul 27, 2019

You shouldn't be calling NtControlTrace without setting the previous mode.

The right convention is to use ZwControlTrace and other Zw functions when operating with kernelmode buffers. In this case, your UNICODE_STRING is allocated in the kernel address space. If you don't set your previous mode (which you can do manually), there may be failures due to extended checks later on.

Anyway, on most machines the circular kernel context logger should already be running and therefore you should be able to interact with it fine with EtwpUpdateTrace.

@niallnsec
Copy link

niallnsec commented Jul 27, 2019

Since the call to NtTraceControl happens as a result of executing DriverEntry, would that not mean that the previous mode will already be set to KernelMode due to it being spawned from a system thread?

@SpriteOvO Out of interest, what error were you getting when compiling with a newer SDK version? I am using version 10.0.17763.0 and currently have it compiling fine.

@SpriteOvO
Copy link

@SpriteOvO Out of interest, what error were you getting when compiling with a newer SDK version? I am using version 10.0.17763.0 and currently have it compiling fine.

When compiling a driver project with a version other than 10.0.16299.0, the regular header file (such as ntddk.h ntifs.h, etc.) cannot be found. Compiling the win32 program is fine.

It should be caused by some errors when I installed wdk.

@xets007
Copy link
Author

xets007 commented Jul 28, 2019

[+] infinityhook: Loaded.
[-] infinityhook: Failed to initialize with status: 0xc0000035.

I got the same failure code as @xets007.

The problem has been solved. It is because of my own stupidity. Thanks to @nmulasmajic for your answers.

@SpriteOvO ,
Can you tell me what your code is?

@SpriteOvO
Copy link

SpriteOvO commented Jul 28, 2019

[+] infinityhook: Loaded.
[-] infinityhook: Failed to initialize with status: 0xc0000035.

I got the same failure code as @xets007.
The problem has been solved. It is because of my own stupidity. Thanks to @nmulasmajic for your answers.

@SpriteOvO ,
Can you tell me what your code is?

Previously my AllocateUnicode function was wrong, I forgot to copy the string, causing the ProviderName content to be empty. 😵

this is new.

UNICODE_STRING AllocateUnicode(WCHAR *Content)
{
	if (Content == NULL) {
		return { 0 };
	}

	UNICODE_STRING Result;
	USHORT StringLength = (USHORT)wcslen(Content);
	USHORT StringSize = StringLength * sizeof(WCHAR);
	USHORT MemorySize = StringSize + sizeof(WCHAR);
	WCHAR *StringBuffer = (WCHAR*)ExAllocatePoolWithTag(NonPagedPool, MemorySize, ALLOC_TAG);

	RtlZeroMemory(StringBuffer, MemorySize);
	RtlCopyMemory(StringBuffer, Content, wcslen(Content) * sizeof(WCHAR));

	Result.Buffer = StringBuffer;
	Result.Length = StringSize;
	Result.MaximumLength = MemorySize;
	Result.Buffer[StringLength] = L'\0';


	return Result;
}
void FreeUnicode(UNICODE_STRING *pUnicodeString)
{
	ExFreePool(pUnicodeString->Buffer);
	RtlZeroMemory(pUnicodeString, sizeof(UNICODE_STRING));
}

@xets007
Copy link
Author

xets007 commented Jul 29, 2019

[+] infinityhook: Loaded.
[-] infinityhook: Failed to initialize with status: 0xc0000035.

I got the same failure code as @xets007.
The problem has been solved. It is because of my own stupidity. Thanks to @nmulasmajic for your answers.

@SpriteOvO ,
Can you tell me what your code is?

Previously my AllocateUnicode function was wrong, I forgot to copy the string, causing the ProviderName content to be empty. 😵

this is new.

UNICODE_STRING AllocateUnicode(WCHAR *Content)
{
	if (Content == NULL) {
		return { 0 };
	}

	UNICODE_STRING Result;
	USHORT StringLength = (USHORT)wcslen(Content);
	USHORT MemorySize = (StringLength + 1) * sizeof(WCHAR);
	WCHAR *StringBuffer = (WCHAR*)ExAllocatePoolWithTag(NonPagedPool, MemorySize, ALLOC_TAG);

	RtlZeroMemory(&Result, sizeof(Result));
	RtlZeroMemory(StringBuffer, MemorySize);
	RtlCopyMemory(StringBuffer, Content, wcslen(Content) * sizeof(WCHAR));

	Result.Buffer = StringBuffer;
	Result.Length = MemorySize;
	Result.MaximumLength = MemorySize;
	Result.Buffer[Result.Length] = L'\0';

	return Result;
}
void FreeUnicode(UNICODE_STRING *pUnicodeString)
{
	ExFreePool(pUnicodeString->Buffer);
	RtlZeroMemory(pUnicodeString, sizeof(UNICODE_STRING));
}

thank you very much! my project can biuld, driver can load,

but callback "IfhpInternalGetCpuClock" not be called!

@SpriteOvO
Copy link

SpriteOvO commented Jul 29, 2019

[+] infinityhook: Loaded.
[-] infinityhook: Failed to initialize with status: 0xc0000035.

I got the same failure code as @xets007.
The problem has been solved. It is because of my own stupidity. Thanks to @nmulasmajic for your answers.

@SpriteOvO ,
Can you tell me what your code is?

Previously my AllocateUnicode function was wrong, I forgot to copy the string, causing the ProviderName content to be empty. 😵

thank you very much! my project can biuld, driver can load,

but callback "IfhpInternalGetCpuClock" not be called!

One thing I forgot to say.
OFFSET_WMI_LOGGER_CONTEXT_CPU_CYCLE_CLOCK is hard-coded in the project, which is different from the offset on Win7.

@xets007
Copy link
Author

xets007 commented Jul 29, 2019

[+] infinityhook: Loaded.
[-] infinityhook: Failed to initialize with status: 0xc0000035.

I got the same failure code as @xets007.
The problem has been solved. It is because of my own stupidity. Thanks to @nmulasmajic for your answers.

@SpriteOvO ,
Can you tell me what your code is?

Previously my AllocateUnicode function was wrong, I forgot to copy the string, causing the ProviderName content to be empty. 😵

thank you very much! my project can biuld, driver can load,
but callback "IfhpInternalGetCpuClock" not be called!

One thing I forgot to say.
OFFSET_WMI_LOGGER_CONTEXT_CPU_CYCLE_CLOCK is hard-coded in the project, which is different from the offset on Win7.

everything is ok, 3Q very much!

@SpriteOvO
Copy link

SpriteOvO commented Jul 29, 2019

[+] infinityhook: Loaded.
[-] infinityhook: Failed to initialize with status: 0xc0000035.

I got the same failure code as @xets007.
The problem has been solved. It is because of my own stupidity. Thanks to @nmulasmajic for your answers.

@SpriteOvO ,
Can you tell me what your code is?

Previously my AllocateUnicode function was wrong, I forgot to copy the string, causing the ProviderName content to be empty. 😵

thank you very much! my project can biuld, driver can load,
but callback "IfhpInternalGetCpuClock" not be called!

One thing I forgot to say.
OFFSET_WMI_LOGGER_CONTEXT_CPU_CYCLE_CLOCK is hard-coded in the project, which is different from the offset on Win7.

everything is ok, 3Q very much!

you are welcome. 😄

@YangKi1902
Copy link

[+] infinityhook: Loaded.
[-] infinityhook: Failed to initialize with status: 0xc0000035.

I got the same failure code as @xets007.
The problem has been solved. It is because of my own stupidity. Thanks to @nmulasmajic for your answers.

@SpriteOvO ,
Can you tell me what your code is?

Previously my AllocateUnicode function was wrong, I forgot to copy the string, causing the ProviderName content to be empty. 😵

thank you very much! my project can biuld, driver can load,
but callback "IfhpInternalGetCpuClock" not be called!

One thing I forgot to say.
OFFSET_WMI_LOGGER_CONTEXT_CPU_CYCLE_CLOCK is hard-coded in the project, which is different from the offset on Win7.

can you tell me how to find OFFSET_WMI_LOGGER_CONTEXT_CPU_CYCLE_CLOCK ?

@SpriteOvO
Copy link

[+] infinityhook: Loaded.
[-] infinityhook: Failed to initialize with status: 0xc0000035.

I got the same failure code as @xets007.
The problem has been solved. It is because of my own stupidity. Thanks to @nmulasmajic for your answers.

@SpriteOvO ,
Can you tell me what your code is?

Previously my AllocateUnicode function was wrong, I forgot to copy the string, causing the ProviderName content to be empty. 😵

thank you very much! my project can biuld, driver can load,
but callback "IfhpInternalGetCpuClock" not be called!

One thing I forgot to say.
OFFSET_WMI_LOGGER_CONTEXT_CPU_CYCLE_CLOCK is hard-coded in the project, which is different from the offset on Win7.

can you tell me how to find OFFSET_WMI_LOGGER_CONTEXT_CPU_CYCLE_CLOCK ?

Read README.md carefully.

@YangKi1902
Copy link

[+] infinityhook: Loaded.
[-] infinityhook: Failed to initialize with status: 0xc0000035.

I got the same failure code as @xets007.
The problem has been solved. It is because of my own stupidity. Thanks to @nmulasmajic for your answers.

@SpriteOvO ,
Can you tell me what your code is?

Previously my AllocateUnicode function was wrong, I forgot to copy the string, causing the ProviderName content to be empty. 😵

thank you very much! my project can biuld, driver can load,
but callback "IfhpInternalGetCpuClock" not be called!

One thing I forgot to say.
OFFSET_WMI_LOGGER_CONTEXT_CPU_CYCLE_CLOCK is hard-coded in the project, which is different from the offset on Win7.

can you tell me how to find OFFSET_WMI_LOGGER_CONTEXT_CPU_CYCLE_CLOCK ?

Read README.md carefully.

got it, thanks :)

@YangKi1902
Copy link

[-] infinityhook: Failed to initialize with status: 0xc0000139.
anyone have this problem on windows 10 1903 latest update ?

@BerkanYildiz
Copy link
Contributor

BerkanYildiz commented Dec 1, 2019

@YangKi1902
Copy link

https://github.com/everdox/InfinityHook/blob/master/src/libinfinityhook/infinityhook.cpp#L150-L153

Long story short: sig broke.

do you know how to fix it, my code look not working :
SectionBase = ImgGetImageSection(NtBaseAddress, ".rdata", &SizeOfSection);
if (!SectionBase)
{
SectionBase = ImgGetImageSection(NtBaseAddress, ".text", &SizeOfSection);
if (!SectionBase)
{
return FALSE;
}
}

@SpriteOvO
Copy link

Why don't you try to fix it yourself? lol

@YangKi1902
Copy link

YangKi1902 commented Dec 1, 2019

Why don't you try to fix it yourself? lol

yeah, why not 👍
here my snippet code to fix it, no need to scan section memory anymore :

typedef struct _DUMP_HEADER
{
ULONG Signature;
ULONG ValidDump;
ULONG MajorVersion;
ULONG MinorVersion;
ULONG_PTR DirectoryTableBase;
ULONG_PTR PfnDataBase;
PLIST_ENTRY PsLoadedModuleList;
PLIST_ENTRY PsActiveProcessHead;
ULONG MachineImageType;
ULONG NumberProcessors;
ULONG BugCheckCode;
ULONG_PTR BugCheckParameter1;
ULONG_PTR BugCheckParameter2;
ULONG_PTR BugCheckParameter3;
ULONG_PTR BugCheckParameter4;
CHAR VersionUser[32];
struct _KDDEBUGGER_DATA64 *KdDebuggerDataBlock;
} DUMP_HEADER, *PDUMP_HEADER;
typedef unsigned long DWORD;

typedef struct _DBGKD_DEBUG_DATA_HEADER64 {

//
// Link to other blocks
//

LIST_ENTRY64 List;

//
// This is a unique tag to identify the owner of the block.
// If your component only uses one pool tag, use it for this, too.
//

ULONG OwnerTag;

//
// This must be initialized to the size of the data block,
// including this structure.
//

ULONG Size;

} DBGKD_DEBUG_DATA_HEADER64, *PDBGKD_DEBUG_DATA_HEADER64;

typedef struct _KDDEBUGGER_DATA64 {

DBGKD_DEBUG_DATA_HEADER64 Header;

//
// Base address of kernel image
//

ULONG64 KernBase;

//
// DbgBreakPointWithStatus is a function which takes an argument
// and hits a breakpoint. This field contains the address of the
// breakpoint instruction. When the debugger sees a breakpoint
// at this address, it may retrieve the argument from the first
// argument register, or on x86 the eax register.
//

ULONG64 BreakpointWithStatus; // address of breakpoint

//
// Address of the saved context record during a bugcheck
//
// N.B. This is an automatic in KeBugcheckEx's frame, and
// is only valid after a bugcheck.
//

ULONG64 SavedContext;

//
// help for walking stacks with user callbacks:
//

//
// The address of the thread structure is provided in the
// WAIT_STATE_CHANGE packet. This is the offset from the base of
// the thread structure to the pointer to the kernel stack frame
// for the currently active usermode callback.
//

USHORT ThCallbackStack; // offset in thread data

//
// these values are offsets into that frame:
//

USHORT NextCallback; // saved pointer to next callback frame
USHORT FramePointer; // saved frame pointer

//
// pad to a quad boundary
//
USHORT PaeEnabled;

//
// Address of the kernel callout routine.
//

ULONG64 KiCallUserMode; // kernel routine

//
// Address of the usermode entry point for callbacks.
//

ULONG64 KeUserCallbackDispatcher; // address in ntdll

//
// Addresses of various kernel data structures and lists
// that are of interest to the kernel debugger.
//

ULONG64 PsLoadedModuleList;
ULONG64 PsActiveProcessHead;
ULONG64 PspCidTable;

ULONG64 ExpSystemResourcesList;
ULONG64 ExpPagedPoolDescriptor;
ULONG64 ExpNumberOfPagedPools;

ULONG64 KeTimeIncrement;
ULONG64 KeBugCheckCallbackListHead;
ULONG64 KiBugcheckData;

ULONG64 IopErrorLogListHead;

ULONG64 ObpRootDirectoryObject;
ULONG64 ObpTypeObjectType;

ULONG64 MmSystemCacheStart;
ULONG64 MmSystemCacheEnd;
ULONG64 MmSystemCacheWs;

ULONG64 MmPfnDatabase;
ULONG64 MmSystemPtesStart;
ULONG64 MmSystemPtesEnd;
ULONG64 MmSubsectionBase;
ULONG64 MmNumberOfPagingFiles;

ULONG64 MmLowestPhysicalPage;
ULONG64 MmHighestPhysicalPage;
ULONG64 MmNumberOfPhysicalPages;

ULONG64 MmMaximumNonPagedPoolInBytes;
ULONG64 MmNonPagedSystemStart;
ULONG64 MmNonPagedPoolStart;
ULONG64 MmNonPagedPoolEnd;

ULONG64 MmPagedPoolStart;
ULONG64 MmPagedPoolEnd;
ULONG64 MmPagedPoolInformation;
ULONG64 MmPageSize;

ULONG64 MmSizeOfPagedPoolInBytes;

ULONG64 MmTotalCommitLimit;
ULONG64 MmTotalCommittedPages;
ULONG64 MmSharedCommit;
ULONG64 MmDriverCommit;
ULONG64 MmProcessCommit;
ULONG64 MmPagedPoolCommit;
ULONG64 MmExtendedCommit;

ULONG64 MmZeroedPageListHead;
ULONG64 MmFreePageListHead;
ULONG64 MmStandbyPageListHead;
ULONG64 MmModifiedPageListHead;
ULONG64 MmModifiedNoWritePageListHead;
ULONG64 MmAvailablePages;
ULONG64 MmResidentAvailablePages;

ULONG64 PoolTrackTable;
ULONG64 NonPagedPoolDescriptor;

ULONG64 MmHighestUserAddress;
ULONG64 MmSystemRangeStart;
ULONG64 MmUserProbeAddress;

ULONG64 KdPrintCircularBuffer;
ULONG64 KdPrintCircularBufferEnd;
ULONG64 KdPrintWritePointer;
ULONG64 KdPrintRolloverCount;

ULONG64 MmLoadedUserImageList;

// NT 5.1 Addition

ULONG64 NtBuildLab;
ULONG64 KiNormalSystemCall;

// NT 5.0 hotfix addition

ULONG64 KiProcessorBlock;
ULONG64 MmUnloadedDrivers;
ULONG64 MmLastUnloadedDriver;
ULONG64 MmTriageActionTaken;
ULONG64 MmSpecialPoolTag;
ULONG64 KernelVerifier;
ULONG64 MmVerifierData;
ULONG64 MmAllocatedNonPagedPool;
ULONG64 MmPeakCommitment;
ULONG64 MmTotalCommitLimitMaximum;
ULONG64 CmNtCSDVersion;

// NT 5.1 Addition

ULONG64 MmPhysicalMemoryBlock;
ULONG64 MmSessionBase;
ULONG64 MmSessionSize;
ULONG64 MmSystemParentTablePage;

// Server 2003 addition

ULONG64 MmVirtualTranslationBase;

USHORT OffsetKThreadNextProcessor;
USHORT OffsetKThreadTeb;
USHORT OffsetKThreadKernelStack;
USHORT OffsetKThreadInitialStack;

USHORT OffsetKThreadApcProcess;
USHORT OffsetKThreadState;
USHORT OffsetKThreadBStore;
USHORT OffsetKThreadBStoreLimit;

USHORT SizeEProcess;
USHORT OffsetEprocessPeb;
USHORT OffsetEprocessParentCID;
USHORT OffsetEprocessDirectoryTableBase;

USHORT SizePrcb;
USHORT OffsetPrcbDpcRoutine;
USHORT OffsetPrcbCurrentThread;
USHORT OffsetPrcbMhz;

USHORT OffsetPrcbCpuType;
USHORT OffsetPrcbVendorString;
USHORT OffsetPrcbProcStateContext;
USHORT OffsetPrcbNumber;

USHORT SizeEThread;

ULONG64 KdPrintCircularBufferPtr;
ULONG64 KdPrintBufferSize;

ULONG64 KeLoaderBlock;

USHORT SizePcr;
USHORT OffsetPcrSelfPcr;
USHORT OffsetPcrCurrentPrcb;
USHORT OffsetPcrContainedPrcb;

USHORT OffsetPcrInitialBStore;
USHORT OffsetPcrBStoreLimit;
USHORT OffsetPcrInitialStack;
USHORT OffsetPcrStackLimit;

USHORT OffsetPrcbPcrPage;
USHORT OffsetPrcbProcStateSpecialReg;
USHORT GdtR0Code;
USHORT GdtR0Data;

USHORT GdtR0Pcr;
USHORT GdtR3Code;
USHORT GdtR3Data;
USHORT GdtR3Teb;

USHORT GdtLdt;
USHORT GdtTss;
USHORT Gdt64R3CmCode;
USHORT Gdt64R3CmTeb;

ULONG64 IopNumTriageDumpDataBlocks;
ULONG64 IopTriageDumpDataBlocks;

// Longhorn addition

ULONG64 VfCrashDataBlock;
ULONG64 MmBadPagesDetected;
ULONG64 MmZeroedPageSingleBitErrorsDetected;

// Windows 7 addition

ULONG64 EtwpDebuggerData;
USHORT OffsetPrcbContext;

// Windows 8 addition

USHORT OffsetPrcbMaxBreakpoints;
USHORT OffsetPrcbMaxWatchpoints;

ULONG OffsetKThreadStackLimit;
ULONG OffsetKThreadStackBase;
ULONG OffsetKThreadQueueListEntry;
ULONG OffsetEThreadIrpList;

USHORT OffsetPrcbIdleThread;
USHORT OffsetPrcbNormalDpcState;
USHORT OffsetPrcbDpcStack;
USHORT OffsetPrcbIsrStack;

USHORT SizeKDPC_STACK_FRAME;

// Windows 8.1 Addition

USHORT OffsetKPriQueueThreadListHead;
USHORT OffsetKThreadWaitReason;

// Windows 10 RS1 Addition

USHORT Padding;
ULONG64 PteBase;

// Windows 10 RS5 Addition

ULONG64 RetpolineStubFunctionTable;
ULONG RetpolineStubFunctionTableSize;
ULONG RetpolineStubOffset;
ULONG RetpolineStubSize;

} KDDEBUGGER_DATA64, *PKDDEBUGGER_DATA64;
KDDEBUGGER_DATA64 g_KdBlock;

typedef ULONG(NTAPI* _KeCapturePersistentThreadState)(
PCONTEXT Context,
PKTHREAD Thread,
ULONG BugCheckCode,
ULONG BugCheckParameter1,
ULONG BugCheckParameter2,
ULONG BugCheckParameter3,
ULONG BugCheckParameter4,
PVOID VirtualAddress
);
_KeCapturePersistentThreadState KeCapturePersistentThreadState;
BOOLEAN InitializeDebuggerBlock()
{
CONTEXT context = { 0 };
context.ContextFlags = CONTEXT_FULL;
RtlCaptureContext(&context);
BOOLEAN ret = FALSE;
PDUMP_HEADER dumpHeader = (PDUMP_HEADER)ExAllocatePool(NonPagedPool, DUMP_BLOCK_SIZE);
if (dumpHeader)
{
UNICODE_STRING SymbolName;
RtlInitUnicodeString(&SymbolName, L"KeCapturePersistentThreadState");
KeCapturePersistentThreadState = (_KeCapturePersistentThreadState)MmGetSystemRoutineAddress(&SymbolName);
if (KeCapturePersistentThreadState)
{
KeCapturePersistentThreadState(&context, NULL, 0, 0, 0, 0, 0, dumpHeader);
RtlCopyMemory(&g_KdBlock, (PUCHAR)dumpHeader + KDDEBUGGER_DATA_OFFSET, sizeof(g_KdBlock));
ret = TRUE;
}
ExFreePool(dumpHeader);
}
return ret;
}

then edit IfhpResolveSymbols function :

static BOOLEAN IfhpResolveSymbols()
{
if (!InitializeDebuggerBlock())
{
return FALSE;
}

EtwpDebuggerData = (PVOID)g_KdBlock.EtwpDebuggerData;

PVOID* EtwpDebuggerDataSilo = (PVOID*)((uintptr_t)EtwpDebuggerData + OFFSET_ETW_DEBUGGER_DATA_SILO);

//
// Pull out the circular kernel context logger.
//
CkclWmiLoggerContext = EtwpDebuggerDataSilo[INDEX_CKCL_LOGGER];

//
// Grab the system call entry value.
//
SystemCallEntryPage = PAGE_ALIGN(ImgGetSyscallEntry());
if (!SystemCallEntryPage)
{
return FALSE;
}

return TRUE;
}

@YangKi1902
Copy link

yes sorry but im just starting everything from internet, just share my fix to who need it. About me, i have nothing to show off.

@Eagle1020
Copy link

是的,很抱歉,但是我只是从互联网开始一切,只是将我的补丁分享给需要的人。关于我,我没什么可炫耀的。

I can't execute normally on win7! [IfhpInternalGetCpuClock] cannot be triggered, can you help me?

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

8 participants