Thread: Segmentation fault!?!?!?

  1. #16
    Reverse Engineer maxorator's Avatar
    Join Date
    Aug 2005
    Location
    Estonia
    Posts
    2,318
    You are dumping only the modules' code, but not the dynamic memory allocated by the process.

    For getting the dynamically allocated memory, you need to enumerate heaps ( GetProcessHeaps() ) and then use HeapWalk() to enumerate memory blocks.
    Last edited by maxorator; 09-23-2008 at 02:12 AM.

  2. #17
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    I don't really recommend GlobalAlloc & things. They are unportable and it is obvious you do not need it for your purposes.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  3. #18
    Registered User
    Join Date
    Jun 2008
    Posts
    161
    Yeah, I don't get this HeapWalking crap. I also don't see an example on MSDN. I saw another thread somewhere suggesting VirtualQueryEx.

  4. #19
    Registered User
    Join Date
    Mar 2005
    Location
    Mountaintop, Pa
    Posts
    1,058
    I'm working on implementing that to see if it solves the problem. I've never used GlobalAlloc though. Is there some reason to choose that over malloc() or realloc()? You also didn't free (GlobalFree?) the memory when it finishes.
    My Bad. I forgot call GlobalFree. Yes, there is definitely a reason why I used GlobalAlloc.GlobalAlloc and LocalAlloc functions provide two blocks of memory: fixed and moveable. Moveable memory could be allocated with the DISCARDABLE flag.When allocating a fixed memory block, the GlobalAlloc and LocalAlloc functions return a pointer to a memory block.

    To work with a fixed memory block is same as working with malloc and the free function of CRT. The pointer returned for a fixed block can be used to free the memory allocated without retrieving a handle to that memory, by calling GlobalHandle function. In the case of moveable memory, instead of a pointer, the handle to the memory is returned. This is to provide an abstract layer over the allocated memory. Heap manager can move this memory block within its heap.

    Moveable memory blocks are much preferable than fixed memory blocks. The system performance is better if we have minimum heap fragmentation. Fixed blocks get allocated at the bottom of the heap, and moveable blocks get locked down at the top. By marking your block moveable, once it has been freed, that free space will quickly be reused by other locked moveable blocks. If another fixed block is allocated, then when the first block is released, it will cause a hole to be created in the fixed memory area.

    In brief, moveable means that a block may be moved in memory during a heap compaction to provide sufficient free space for other allocation requests. Discardable means that a block may be stored to disk and retrieved later, when needed again. Locked memory blocks are not moved or discarded. A fixed memory block will never be moved or discarded.

    Also, check this post. It may be of some help to you. Finally, I also could not figure out how to use HeapWalk to traverse the dynamic memory of a remote process.

  5. #20
    Banned master5001's Avatar
    Join Date
    Aug 2001
    Location
    Visalia, CA, USA
    Posts
    3,685
    Quote Originally Posted by Elysia View Post
    I don't really recommend GlobalAlloc & things. They are unportable and it is obvious you do not need it for your purposes.
    Well even Windows Mobile supports GlobalAlloc() so it isn't that unportable. For clipboard operations you actually have to use GlobalAlloc() exclusively. The HeapWalking stuff is soooo grossly underdocumented by microsoft that it isn't even funny (which is why I didn't even dignify them enough to capitalize their name).

  6. #21
    Registered User
    Join Date
    Jun 2008
    Posts
    161
    I find it hard to believe that there aren't any decent examples of how to determine the size of a process and dump ALL of its memory like all these cheat search tools do.

  7. #22
    'Allo, 'Allo, Allo
    Join Date
    Apr 2008
    Posts
    639
    The heap walking isn't hard if you just apply yourself a little. Here's a crude implementation that'll search the heap memory and main module of whatever process the code is in (obviously it's own if you just compile and run this).

    Code:
    #define WIN32_LEAN_AND_MEAN
    #define _WIN32_WINNT 0x0500
    
    #include <windows.h>
    #include <vector>
    #include <algorithm>
    #include <typeinfo>
    #include <iostream>
    #include <iterator>
    #include <psapi.h>
    
    template<class T>
    void FindTypeInBlock(LPVOID base, SIZE_T size, std::vector<LPCVOID>& result, const T& valToFind)
    {
        SIZE_T elements = size / sizeof(T);
        if(elements < 1)
        {
            return;
        }
        const T* const baseAsT = reinterpret_cast<T*>(base);
        std::vector<T> range(baseAsT, baseAsT + elements);
        typename std::vector<T>::iterator iter = range.begin();
        while((iter = std::find(iter, range.end(), valToFind)) != range.end())
        {
            const LPCVOID address = baseAsT + (iter - range.begin());
            result.push_back(address);
            ++iter;
        }
    }
    
    int main()
    {
        std::vector<HANDLE> heaps(GetProcessHeaps(0, NULL));
        GetProcessHeaps(heaps.size(), &heaps[0]);
        std::vector<LPCVOID> results;
        // change this to whatever type and value you want to search for
        int val = 28;
        for(DWORD i = 0; i < heaps.size(); ++i)
        {
            std::cout << "Heap handle:\t" << heaps[i] << '\n';
            PROCESS_HEAP_ENTRY phi = {0};
            while(HeapWalk(heaps[i], &phi))
            {
                std::cout << "Block Start Address: " << phi.lpData << '\n';
                std::cout << "\tSize: " << phi.cbData << " - Overhead: "
                               << static_cast<DWORD>(phi.cbOverhead) << '\n';
                std::cout << "Block is a";
                if(phi.wFlags & PROCESS_HEAP_REGION)
                {
                    std::cout << " VMem region\n";
                    std::cout << "\tCommitted size: " << phi.Region.dwCommittedSize << '\n';
                    std::cout << "\tUncomitted size: " << phi.Region.dwUnCommittedSize << '\n';
                    std::cout << "\tFirst block: " << phi.Region.lpFirstBlock << '\n';
                    std::cout << "\tLast block: " << phi.Region.lpLastBlock << '\n';
                }
                else 
                {
                    if(phi.wFlags & PROCESS_HEAP_UNCOMMITTED_RANGE)
                    {
                        std::cout << "n uncommitted range\n";
                    }
                    else if(phi.wFlags & PROCESS_HEAP_ENTRY_BUSY)
                    {
                        std::cout << "n Allocated range: Region index - " 
                                       << static_cast<unsigned>(phi.iRegionIndex);
                        if(phi.wFlags & PROCESS_HEAP_ENTRY_MOVEABLE)
                        {
                            std::cout << "\n\tMovable: Handle is 0x" << phi.Block.hMem << '\n';
                        }
                        else if(phi.wFlags & PROCESS_HEAP_ENTRY_DDESHARE)
                        {
                            std::cout << "\n\tDDE Sharable\n";
                        }
                        else std::cout << std::endl;
    
                        // check this block for the data
                        FindTypeInBlock(phi.lpData, phi.cbData, results, val);
                    }
                }
                std::cout << std::endl;
            }
        }
        // now check the module, for static data
        MODULEINFO modInf = {0};
        GetModuleInformation(GetCurrentProcess(), GetModuleHandle(NULL), &modInf, sizeof(MODULEINFO));
        FindTypeInBlock(modInf.lpBaseOfDll, modInf.SizeOfImage, results, val);
        std::cout << "The " << typeid(val).name() << ' ' << val
                       << " was found at the following locations:\n";
        std::copy(results.begin(), results.end(),
                        std::ostream_iterator<LPCVOID>(std::cout, "\n"));
    }
    Last edited by adeyblue; 09-23-2008 at 08:44 PM.

  8. #23
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by master5001 View Post
    Well even Windows Mobile supports GlobalAlloc() so it isn't that unportable. For clipboard operations you actually have to use GlobalAlloc() exclusively. The HeapWalking stuff is soooo grossly underdocumented by microsoft that it isn't even funny (which is why I didn't even dignify them enough to capitalize their name).
    Yes, but platform specific APIs are unportable, as we know.
    If there's no need to use them (oh, they DO exist for a reason, and they are useful), then one shouldn't use them in favor of portability.
    GlobalAlloc isn't a requirement in this code from what I see (not would I think, is there a sufficiently good reason to use it), so using malloc/free is better.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  9. #24
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by Elysia View Post
    Yes, but platform specific APIs are unportable, as we know.
    If there's no need to use them (oh, they DO exist for a reason, and they are useful), then one shouldn't use them in favor of portability.
    GlobalAlloc isn't a requirement in this code from what I see (not would I think, is there a sufficiently good reason to use it), so using malloc/free is better.
    Considering that the REST of the code is full of Windows API calls, I'd say that trying to write 5% of the code portably will make little difference.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  10. #25
    Registered User
    Join Date
    Mar 2005
    Location
    Mountaintop, Pa
    Posts
    1,058
    The heap walking isn't hard if you just apply yourself a little. Here's a crude implementation that'll search the heap memory and main module of whatever process the code is in (obviously it's own if you just compile and run this).
    I'm not so sure this code is totally reliable. I've changed the value of the val int to 9999 and it did not find it. I've also tried accessing a remote process to find a global int variable with the value of 9999 and it did not find it.

  11. #26
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Huh? I just built the code and it finds the value I enter at least once (at 43BF28, but I expect that will vary depending on which compiler it is built with and other factors).

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  12. #27
    Registered User
    Join Date
    Mar 2005
    Location
    Mountaintop, Pa
    Posts
    1,058
    I've attached an ASCII text file which captured the output of the executable for review.

    Also, val = 28 works for me. I get the following:

    The int 28 was found at the following locations:
    004287FC
    00428A38
    I've also tried setting val to 12345 and it was not found.
    Last edited by BobS0327; 09-24-2008 at 07:19 AM.

  13. #28
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Actually, you are right, as soon as you try to use it for a different process, there it doesn't work. GetProcessHeaps() only works on the current process. I couldn't find any other function doing something similar.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  14. #29
    Registered User
    Join Date
    Mar 2005
    Location
    Mountaintop, Pa
    Posts
    1,058
    I've been testing the code both ways. But even accessing the local process does not always produce a found memory location:


    Code:
    The int 101 was found at the following locations:
    0042341C
    00423448
    00424A58
    00424C7C
    00425A08
    The following values used for val in a local process are not found in memory:

    98765
    45678
    12345
    23456
    34567
    35471

  15. #30
    Registered User
    Join Date
    Mar 2005
    Location
    Mountaintop, Pa
    Posts
    1,058
    I find it hard to believe that there aren't any decent examples of how to determine the size of a process and dump ALL of its memory like all these cheat search tools do.
    I'll probably get in trouble with the mods for demonstrating cheat search tools 101. But anyway, the first listing is the target executable. The variable is initially set to "Bob". Start the target executable and then run the second executable which will change this variable from "Bob" to "Ted". Hitting any key in the target executable will display the new value which is "Ted".

    The second executable will need the ProcessId of the the target as command line input.

    Code:
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    #include <conio.h>
    char test[4] = {"Bob"};
    int main(void)
    {
    	printf("Before WriteProcessmemory update %s\n\n Hit any key to display new value\n\n", test);
    	getch();
    	printf("After WriteProcessMemory update  %s\n", test);
    	getch();
    	return 0;
    }

    Code:
    #pragma comment(lib, "advapi32.lib")
    #pragma comment(lib, "psapi.lib")
    
    #include <windows.h>
    #include <stdio.h>
    #include <psapi.h>
    // Binary equivalent of "Bob" which is used in search 
    const BYTE bPattern[3]={0x42, 0x6f, 0x62};
    
    BOOL EnableTokenPrivilege (LPTSTR privilege)
    {
    	HANDLE hToken;                        
    	TOKEN_PRIVILEGES token_privileges;                  
    	DWORD dwSize;                        
    	ZeroMemory (&token_privileges, sizeof (token_privileges));
    	token_privileges.PrivilegeCount = 1;
    	if ( !OpenProcessToken (GetCurrentProcess(), TOKEN_ALL_ACCESS, &hToken))
    		return FALSE;
    	if (!LookupPrivilegeValue ( NULL, privilege, &token_privileges.Privileges[0].Luid))
    	{ 
    		CloseHandle (hToken);
    		return FALSE;
    	}
    
    	token_privileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
    	if (!AdjustTokenPrivileges ( hToken, FALSE, &token_privileges, 0, NULL, &dwSize))
    	{ 
    		CloseHandle (hToken);
    		return FALSE;
    	}
    	CloseHandle (hToken);
    	return TRUE;
    }
    
    BOOL SearchProcessMemory(int iProcessId)
    {
    	DWORD  cbRead, cbNeeded, iIndex;
    	HMODULE hModule;
    	MODULEINFO ModuleInfo;
    	BYTE *bBuffer = 0; 
    	HANDLE hProcess=OpenProcess(PROCESS_ALL_ACCESS,FALSE, iProcessId);
    	EnumProcessModules(hProcess, &hModule, sizeof(hModule), &cbNeeded);
    	GetModuleInformation(hProcess, hModule, &ModuleInfo, sizeof(MODULEINFO));
    	bBuffer = (LPBYTE)GlobalAlloc(GMEM_FIXED, ModuleInfo.SizeOfImage+1);
    	ReadProcessMemory(hProcess, ModuleInfo.lpBaseOfDll, bBuffer, ModuleInfo.SizeOfImage, &cbRead);
    	//Search the entire memory of our target process
    	for( iIndex = 0; iIndex < ModuleInfo.SizeOfImage; iIndex++)
    	{
    		if (!memcmp(&bBuffer[iIndex], bPattern, 3))
    		{ 
    			// calculate of lpBaseOfDll (start of exe + i)
    			DWORD dwFoundAtAddress = (DWORD)ModuleInfo.lpBaseOfDll + iIndex;
    			printf("we found it at 0x%2X\n", dwFoundAtAddress);
    			// Binary equivalent of "Ted"
    			const BYTE bPatternOut[3]={0x54, 0x65, 0x64};
    			DWORD dwOrgProtect;
    			// By default memory is read only, change it to read/write
    			if(!VirtualProtectEx(hProcess,(LPVOID) dwFoundAtAddress , sizeof(bPatternOut), PAGE_READWRITE, &dwOrgProtect ))
    			{
    				printf("Virtual protect failed error %d\n", GetLastError());
    				return FALSE;
    			}   
    			if (!WriteProcessMemory(hProcess, (LPVOID) dwFoundAtAddress, &bPatternOut, 3, &cbRead))
    				printf("WriteProcessMemory error %d\n", GetLastError());
    			else    printf("WriteProcessMemory successful\n");
    			// Change memory back to read only
    			VirtualProtectEx(hProcess, (LPVOID) dwFoundAtAddress ,sizeof(bPatternOut) , dwOrgProtect , &dwOrgProtect );
    			return TRUE;
    		}
    	}
    	return FALSE;
    }
    
    int main(int argc, char **argv)
    {
    	if ( !EnableTokenPrivilege (SE_DEBUG_NAME) )
    	{
    		printf ( "Cannot get required privilege %lu\n", GetLastError () );
    		return 0;
    	}
    	if(SearchProcessMemory(atoi(argv[1])) == FALSE)
    		printf("Binary signature NOT found\n");
    	return 0;
    }

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Segmentation fault problem
    By odedbobi in forum Linux Programming
    Replies: 1
    Last Post: 11-19-2008, 03:36 AM
  2. Segmentation fault
    By bennyandthejets in forum C++ Programming
    Replies: 7
    Last Post: 09-07-2005, 05:04 PM
  3. Segmentation fault
    By NoUse in forum C Programming
    Replies: 4
    Last Post: 03-26-2005, 03:29 PM
  4. Locating A Segmentation Fault
    By Stack Overflow in forum C Programming
    Replies: 12
    Last Post: 12-14-2004, 01:33 PM
  5. Segmentation fault...
    By alvifarooq in forum C++ Programming
    Replies: 14
    Last Post: 09-26-2004, 12:53 PM