• 0

Problems with memory reading inside injected dll (VirtualProtect)


Question

Hi all,

(deep breath)

So, I have an injected dll that is constantly looping the following code:

long startAddress = atol(szRecvBufferSplit);
szRecvBufferSplit = strtok(NULL, "|");
int numberOfBytes = atoi(szRecvBufferSplit);

MEMORY_BASIC_INFORMATION mbi;

if(VirtualQuery((LPCVOID)startAddress, &mbi, sizeof(mbi)))
{
if (&mbi && mbi.State == MEM_COMMIT && mbi.Protect != PAGE_NOACCESS && mbi.Protect != PAGE_GUARD)
{
if(VirtualProtect((LPVOID)startAddress, numberOfBytes, PAGE_EXECUTE_READWRITE, &dwOldProtect))
{
//if(safeMethod)
//memcpy(szSendBuffer, (void*)startAddress, numberOfBytes);
for(int i = 0; i < numberOfBytes; i++)
{
szSendBuffer[i] = *(unsigned char*)(startAddress + i);
}
VirtualProtect((LPVOID)startAddress, numberOfBytes, dwOldProtect, &dwOldProtect);
}
}
}

The intent of the following code is to read memory without calling ReadProcessMemory and is part of a memory scanning application that I've written. The application scans all of the process' private memory once, and then when it begins a second iteration, it will crash.

The crash occurs when memory is read, after VirtualProtect reports a successful operation. As you can determine from the code, the memory region I am unprotecting and reading from is committed and accessible.

I'm completely baffled as to why reading memory a second time is causing a crash.

7 answers to this question

Recommended Posts

  • 0

First, what is the error/exception code that the kernel raises when your program dies?

Second, why are you using numberOfBytes instead of mbi.RegionSize? And if you insist on using numberOfBytes, you need to check it against mbi.RegionSize because if the former exceeds the latter (perhaps if a page was decommitted in the interim), then this code will blow up.

BTW, there is no need to check to make sure that &mbi is non-NULL since you're allocating that on the stack.

PS: Oh, and I assume that your code has already ensured that the receiving buffer is always large enough, even if numberOfBytes changes between reads? (BTW, sz denotes a string with a zero termination, so unless you are grabbing C strings, you should not use the sz prefix in the variable name, since that's potentially confusing.)

Edited by kliu0x52
  • 0

if(VirtualQuery((LPCVOID)startAddress, &mbi, sizeof(mbi)))

{

if (mbi.State == MEM_COMMIT && mbi.Protect != PAGE_NOACCESS && mbi.Protect != PAGE_GUARD)

{

if(VirtualProtect((LPVOID)startAddress, numberOfBytes, PAGE_EXECUTE_READWRITE, &dwOldProtect))

{

if(!IsBadReadPtr((LPCVOID)startAddress, numberOfBytes))

{

//if(safeMethod)

//memcpy(szSendBuffer, (void*)startAddress, numberOfBytes);

for(int i = 0; i < numberOfBytes; i++)

{

sendBuffer = *(unsigned char*)(startAddress + i);

}

}

VirtualProtect((LPVOID)startAddress, numberOfBytes, dwOldProtect, &dwOldProtect);

}

}

}

Causes either:

Problem Event Name: APPCRASH

Application Name: hl.exe

Application Version: 1.1.1.1

Application Timestamp: 3fd11900

Fault Module Name: ntdll.dll

Fault Module Version: 6.1.7127.0

Fault Module Timestamp: 4a03d5a1

Exception Code: c0000005

Exception Offset: 0001fd37

Or, sometimes (I cannot reproduce it at the moment), the Fault module name is StackHash_XXXX (where XXXX is a hex number)

StackHash is not a module, and googling the error provides little useful information.

I tried de-protecting each page that my memory region to scan resides on (startAddress to startAddress+numberOfBytes), and it still crashed. I may have screwed up the code, however.

  • 0

Well, the nature of the crash report seems to suggest that you are doing something to corrupt memory. It could be some error elsewhere in your program that is being stepped on by this piece of code.

And my second concern? That you should be using mbi.RegionSize instead? Note that these operations that you are using work on entire pages, so you want to be sure that your start address and sizes are correct (both of which should be in increments of 0x1000). And is it really necessary to change the protection mode of pages? Of the three types that you shouldn't read from, you're already exempting no-access and guard pages, leaving you with execute-only pages, which are usually just the contents of the executable part of the PE image.

In any case, I've never tried to do what you're doing, so beyond some generalities, I can't offer any more advice.

Edited by kliu0x52
  • 0

Thanks for your help :)

I tweaked two things. I reduced the scan "chunk" size (numberOfBytes) from 0x5000 to 0x1000, and I changed the code that loops to:

if(!IsBadReadPtr((LPCVOID)startAddress, numberOfBytes))
						{
							//if(safeMethod)
							//memcpy(sendBuffer, (void*)startAddress, numberOfBytes);
							for(int i = 0; i &lt; numberOfBytes; i++)
							{
								sendBuffer[i] = *(unsigned char*)(startAddress + i);
							}
						}

And it still crashes... The crazy thing is that this is the only part of the program that directly deals with memory. The rest is in C#, for crying out loud.

Oh, and I've been leaving that commented out memcpy in there because it is causing the crash as well.

  • 0

And here's the strange StackHash error:

Problem Event Name: APPCRASH

Application Name: hl.exe

Application Version: 1.1.1.1

Application Timestamp: 3fd11900

Fault Module Name: StackHash_e98d

Fault Module Version: 0.0.0.0

Fault Module Timestamp: 00000000

Exception Code: c0000005

Exception Offset: 004d004f

  • 0

A StackHash crash just means that the location of the crash does not correspond to any module; it's just a hash of the stack trace so that a unique-ish name can be used in place of a module name. Normally, this would suggest a memory corruption, but you just mentioned that you are using C#, and that explains a lot. To put it simply, you should not be doing what you are doing using managed code. Injecting code is messy, especially if .NET is in the picture, and there is a good reason why ReadProcessMemory is preferred. I have no idea what you are trying to do, but whatever it is, I think you should rethink your approach.

  • 0

There seems to be a general issue with checking if memory is readable/writable. IsBadReadPtr has been dubbed "CrashMyProgram" by some. It appears that I may need to do a 'smarter' iteration through memory, rather than just doing continuous scans of 4 kb of memory.

This topic is now closed to further replies.
  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Posts

    • https://www.neowin.net/news/tags/mastodon/ In short: Federated Twitter (X)
    • Keep in mind it was purchased by an advertising company. I use SearxNG.
    • I am using Waterfox Private Search now that I started using the Waterfox browser on my PC and Android. Both work great* search waterfox net with full stops in between. * I have an issue where making comments on articles on various websites is difficult with Waterfox on Android as it randomly adds spaces and doubles up on text.
    • I can't believe it was only two years since the last time MS raised their prices and now they think they can do it again so soon. Of course they needed to backtrack on this. I hope Nintendo is next.
    • I guess I gotta be even more specific then since I'm looking for an absolute confirmation.  The mini PC has never booted up or powered on by me. I'm assuming it'll be like buying a new PC from a store. Nothing is set up. Like absolutely nothing on the mini PC because I can't emphasize this enough. My USB drive already has Windows set up on it from my other desktop so I know it's clean. So now I connect it to the mini PC before it's even booted up or go to the desktop. I then turn on the mini PC and boot into the USB drive. I should see an existing partition. I'll delete it and then install Windows again over the entire drive. I don't necessarily want to create a separate partition. Once it installs and boots to the desktop, I'm assuming the drive is "clean" and free of any malware/viruses. Basically, this process will eliminate any potential for malware/viruses to still somehow hide in the SSD and then potentially affect me later.  I'm being very anal about this because I really don't trust anything bought from AliExpress, but the price was very tempting.  Is Windows Defender reliable? Afterwards, if I do a full scan and it doesn't find anything in the SSD and the USB drive, can I be confident the mini PC is now safe and secured to enter my banking credentials? If not, what else can I do to be absolutely certain?
  • Recent Achievements

    • Collaborator
      fernan99 earned a badge
      Collaborator
    • Collaborator
      MikeK13 earned a badge
      Collaborator
    • One Month Later
      Alexander 001 earned a badge
      One Month Later
    • One Month Later
      Antonio Barboza earned a badge
      One Month Later
    • Week One Done
      Antonio Barboza earned a badge
      Week One Done
  • Popular Contributors

    1. 1
      +primortal
      584
    2. 2
      ATLien_0
      219
    3. 3
      Michael Scrip
      170
    4. 4
      Xenon
      136
    5. 5
      +FloatingFatMan
      123
  • Tell a friend

    Love Neowin? Tell a friend!