Example #1
0
bool SymbolMap::GetSymbolInfo(SymbolInfo *info, u32 address, SymbolType symmask) const
{
	u32 functionAddress = -1;
	u32 dataAddress = -1;

	if (symmask & ST_FUNCTION)
		functionAddress = GetFunctionStart(address);

	if (symmask & ST_DATA)
		dataAddress = GetDataStart(address);

	if (functionAddress == -1 || dataAddress == -1)
	{
		if (functionAddress != -1)
		{
			if (info != NULL)
			{
				info->type = ST_FUNCTION;
				info->address = functionAddress;
				info->size = GetFunctionSize(functionAddress);
			}

			return true;
		}
		
		if (dataAddress != -1)
		{
			if (info != NULL)
			{
				info->type = ST_DATA;
				info->address = dataAddress;
				info->size = GetDataSize(dataAddress);
			}

			return true;
		}

		return false;
	}

	// if both exist, return the function
	if (info != NULL)
	{
		info->type = ST_FUNCTION;
		info->address = functionAddress;
		info->size = GetFunctionSize(functionAddress);
	}

	return true;
}
Example #2
0
std::vector<SymbolEntry> SymbolMap::GetAllSymbols(SymbolType symmask) {
	std::vector<SymbolEntry> result;

	if (symmask & ST_FUNCTION) {
		lock_guard guard(lock_);
		for (auto it = activeFunctions.begin(); it != activeFunctions.end(); it++) {
			SymbolEntry entry;
			entry.address = it->first;
			entry.size = GetFunctionSize(entry.address);
			const char* name = GetLabelName(entry.address);
			if (name != NULL)
				entry.name = name;
			result.push_back(entry);
		}
	}

	if (symmask & ST_DATA) {
		lock_guard guard(lock_);
		for (auto it = activeData.begin(); it != activeData.end(); it++) {
			SymbolEntry entry;
			entry.address = it->first;
			entry.size = GetDataSize(entry.address);
			const char* name = GetLabelName(entry.address);
			if (name != NULL)
				entry.name = name;
			result.push_back(entry);
		}
	}

	return result;
}
Example #3
0
// Taken from Ashkbiz Danehkar's PE protector code:
// (http://www.codeproject.com/cpp/peprotector1.asp)
//
// Return the bytes of a named function.
char* CopyFunction(void (*Body)(void)) {
    DWORD dwSize=GetFunctionSize(Body);
    char* pFuncBody=(char *) Body;
    char* filebuff=new char[dwSize+1];
    CopyMemory(filebuff,pFuncBody,dwSize);
    return(filebuff);
}
Example #4
0
//************************************
// Method:    CJmpSwapDetour
// FullName:  CJmpSwapDetour::CJmpSwapDetour
// Access:    public 
// Parameter: void * function
// Parameter: void * detour
//************************************
CJmpSwapDetour::CJmpSwapDetour(void *function, void *detour) : 
	m_bDetoured(false), 
	m_Target(function), 
	m_Detour(detour),
	m_Jmp(NULL),
	m_JmpSize(0)
{
	m_Target = FollowJmp(m_Target);
	m_Detour = FollowJmp(m_Detour);

	m_FunctionSize = GetFunctionSize(m_Target);

	m_OriginalBytes = new unsigned char[m_FunctionSize];
	memcpy_s(m_OriginalBytes, m_FunctionSize, m_Target, m_FunctionSize);

	BuildJump(m_Detour);

	Swap();
}
Example #5
0
bool SymbolMap::GetSymbolInfo(SymbolInfo *info, u32 address, SymbolType symmask) const {
	u32 functionAddress = INVALID_ADDRESS;
	u32 dataAddress = INVALID_ADDRESS;

	if (symmask & ST_FUNCTION) {
		functionAddress = GetFunctionStart(address);

		// If both are found, we always return the function, so just do that early.
		if (functionAddress != INVALID_ADDRESS) {
			if (info != NULL) {
				info->type = ST_FUNCTION;
				info->address = functionAddress;
				info->size = GetFunctionSize(functionAddress);
				info->moduleAddress = GetFunctionModuleAddress(functionAddress);
			}

			return true;
		}
	}

	if (symmask & ST_DATA) {
		dataAddress = GetDataStart(address);
		
		if (dataAddress != INVALID_ADDRESS) {
			if (info != NULL) {
				info->type = ST_DATA;
				info->address = dataAddress;
				info->size = GetDataSize(dataAddress);
				info->moduleAddress = GetDataModuleAddress(dataAddress);
			}

			return true;
		}
	}

	return false;
}
Example #6
0
// Most of the work is done in main()...
int main( int argc, char* argv[] ) {

  // Print out help message if needed.
  if (argc != 2) {
      printf("*** Code Crypt 0.0 by [email protected] ***\n");
      printf("***                                                 ***\n");
      printf("*** Usage: codecrypt filename.exe                   ***\n");
      printf("*** Will encrypt the codesection to avoid detection ***\n");
      printf("*** Disclaimer: This software is for educational    ***\n");
      printf("*** purposes only.  No responsibility is held or    ***\n");
      printf("*** accepted for misuse.                            ***\n");
      return 0;
    }
  
  // The file to pack is the 1st argument.
  LPCSTR fileName = argv[1];

  // Open the .exe file to be packed.
  HANDLE hFile = CreateFileA(
                             fileName,
			     GENERIC_WRITE | GENERIC_READ,
			     FILE_SHARE_READ | FILE_SHARE_WRITE,
			     NULL,
			     OPEN_EXISTING,
			     FILE_ATTRIBUTE_NORMAL,
			     NULL);

  // Did the file open work?
  if (hFile == INVALID_HANDLE_VALUE) {
    DWORD x = GetLastError();
    // No, get out.
    printf("Cannot open file '%s'...exiting!\n", argv[1]);
    char *buf;
    FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
		  FORMAT_MESSAGE_FROM_SYSTEM |
		  FORMAT_MESSAGE_IGNORE_INSERTS,
		  NULL,x,0,
		  (LPTSTR) &buf,0,NULL);
    printf("Error: %d, Error Code:%d\n", buf, x);
    return 1;
  }

  // Get size of file. This is needed because we need to tell the
  // CreateFileMapping function to add memory to the end of the
  // memory-mapped file. We will later use this memory to add in the
  // unpacker stub and its required data.
  LARGE_INTEGER bigInt;
  BOOL r = GetFileSizeEx(hFile, &bigInt);
  if (!r) {
    printf("Cannot get file size.\n");
    return 1;
  }

  // Is the file too big to add in the unpacker stub?
  DWORD fileSize = bigInt.LowPart;
  if (fileSize + 0x2000 >= ULONG_MAX) {
    printf("The file is too big to pack.\n");
    return 1;
  }

  // Create a handle to a memory mapped file. Note that this does not
  // actually map the file, it just creates the handle that will actually be
  // mapped later. Note that extra space is allocated at the end to
  // the mapped file for the unpacker stub.
  HANDLE hFileMap = CreateFileMapping(hFile, 
				      NULL, 
				      PAGE_READWRITE,
				      bigInt.HighPart,
				      bigInt.LowPart + 0x2000 ,
				      NULL);
    
  // Did creating the file mapping handle work?
  if (hFileMap == NULL) {
    printf("Unable to create file mapping! Exiting...");
    return 1;
  }

  // Map the .exe file into memory. The map is set up so we can read and
  // write to it.
  LPVOID hMap = MapViewOfFile(hFileMap, FILE_MAP_ALL_ACCESS, 0, 0, 0);

  // Did mapping the file to memory work?
  if (hMap == NULL) {
    printf("Unable to map file into memory! Exiting...");
    return 1;
  }

  // Get the DOS header from the .exe file. This is the 1st thing in the
  // file.
  PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)hMap;

  // This packer only works with .exe files. Make sure we have one.
  // The e_magic field tells us what sort of file this is.
  if (!(pDosHeader->e_magic == IMAGE_DOS_SIGNATURE)) {
    printf("This packer only works with .exe files.\n");
    return 1;
  }

  // Get the IMAGE_NT_HEADER. This has 3 fields, the signature (which should
  // be set 0x00004550 for valid PE files), the file header, and the
  // optional file header.
  PIMAGE_NT_HEADERS pNTHeader;
  // The e_lfanew field in the DOS header gives us the offset to the
  // IMAGE_NT_HEADER.
  pNTHeader = MakePtr(PIMAGE_NT_HEADERS, pDosHeader, pDosHeader->e_lfanew);

  // Check to make sure this is a PE file we are working with.
  if (!(pNTHeader->Signature == IMAGE_NT_SIGNATURE)) {
    printf("This packer only works with PE files.\n");
    printf("Signature for PE files is %x. Current signature is %x\n",
           IMAGE_NT_SIGNATURE, pNTHeader->Signature);
    return 1;
  }

  // The entire .exe image is stored in a HMODULE structure. Cast the memory
  // mapped file so it can be viewed as an HMODULE.
  HMODULE *hModule = (HMODULE *) hMap;

  // Grab a pointer to the IMAGE_OPTIONAL_HEADER structure, which contains
  // information about the size of the code and all data sections, where to
  // find the sections, etc.
  //
  // The IMAGE_OPTIONAL_HEADER structure is contained in the IMAGE_NT_HEADER
  // in the OptionalHeader field.
  //
  // Note that we are assuming that we are working with a 32bit executable.
  PIMAGE_OPTIONAL_HEADER32 optionHeader =
    (PIMAGE_OPTIONAL_HEADER32) &(pNTHeader->OptionalHeader);

  // Get the RVA (relative virtual address) of the first byte of code when
  // loaded into memory. To find the actual address of the code add the load
  // address (in this case the address of hModule) to the RVA.
  VOID* baseCodeRVA = (VOID*)optionHeader->BaseOfCode;

  // Get the combined size of all code sections.
  DWORD codeSize = optionHeader->SizeOfCode;

  // TCC does not seem to set the SizeOfCode field, so executables
  // compiled with TCC cannot be packed with this packer.
  if (codeSize < 1) {
    printf("SizeOfCode field is < 1. Cannot pack.\n");
    printf("The execuatble may have been compiled with TCC.\n");
    return 1;
  }

  // After the MAGE_NT_HEADERS is the section table. The section table is an
  // array of IMAGE_SECTION_HEADERs structures. An IMAGE_SECTION_HEADER
  // provides information about its associated section.
  //
  // Use the IMAGE_FIRST_SECTION macro defined in winnt.h to get the address
  // of the 1st IMAGE_SECTION_HEADER.

  // DQ (4/23/2017): I don't see that this macro will work with WINE (modified to support testing).
  // IMAGE_SECTION_HEADER* firstSectionHeader = 
  //  IMAGE_FIRST_SECTION32(pNTHeader);
  IMAGE_SECTION_HEADER* firstSectionHeader = NULL;

  // Get a pointer to the code block. The code block is found by adding the
  // base load address to the code RVA.
  PVOID codePtr = MakePtr(void *, hModule, baseCodeRVA);

  // Unprotect the code so we can encrypt it in place.
  DWORD oldProt = 0;
  BOOL diditwork = 
    VirtualProtect(codePtr, codeSize, PAGE_READWRITE, &oldProt);
    
  // Did the code unprotection work?
  if (!diditwork) {
    DWORD x = GetLastError();
    printf("Cannot unprotect code (error code %d).\n", x);
    return 0;
  }

  // Find the section containing the code. We have already
  // calculated the code relative virtual base address
  // (baseCodeRVA), so now we need to find the section whose base
  // RVA is the same as the RVA of the code.
  IMAGE_SECTION_HEADER* codeSection = 
    FindSection(firstSectionHeader, 
		pNTHeader->FileHeader.NumberOfSections, 
		(DWORD) baseCodeRVA);

  // Can we find the section with the code?
  if (codeSection == NULL) {
    printf("Cannot find code section.\n");
    return 0;
  }

  // Get the raw memory address (inside HMODULE) and size of the code.
  DWORD rawCodePosition = codeSection->PointerToRawData;
  DWORD virtualCodeSize = codeSection->Misc.VirtualSize;

  // Compute the actual, in-memory start and end address of the code
  // block.
  DWORD startpos = (DWORD)hModule + (DWORD)rawCodePosition;
  DWORD endpos = startpos + virtualCodeSize;
 
  // Encrypt the code by incrementing each byte in the code by 1.
  printf("Starting to encrypt code section...\n");
  DWORD currAddr;
  for (currAddr = startpos; currAddr < endpos; currAddr++) {
    (*((char *) currAddr))++;
  }
  printf("Done encrypting code section.\n");

  // Get the last section. We will be tacking the unpacking code
  // onto the end of the last section (if we have room).
  IMAGE_SECTION_HEADER* lastSection = 
    FindLastSection(firstSectionHeader, 
		    pNTHeader->FileHeader.NumberOfSections);

  char sectName[10];
  int i;
  for (i = 0; i < 8; i++) {
    sectName[i] = lastSection->Name[i];
  }
  sectName[8] = '\0';
  printf("Adding stub to section: name = %s, Raw size = %d, Raw Data ptr = %d\n", 
         sectName, 
	 lastSection->SizeOfRawData, 
	 lastSection->PointerToRawData);
    
  // We will be adding the unpacker stub to the last section in the
  // PE file. In that section, we will be adding the unpacker stub
  // code right after the existing data in the section.
  DWORD* storageSpot = (DWORD*)((DWORD)hModule + 
				(DWORD)lastSection->PointerToRawData +
				(DWORD)lastSection->SizeOfRawData);

  // Get the unpacking code and store it in a contiguous chunk of memory.
  char *decryptRoutine = CopyFunction(&DecryptAndStart);
  DWORD decryptSize = GetFunctionSize(&DecryptAndStart);
  if (decryptSize > 0x2000) {
    printf("Decryption routine too large.\n");
    return 1;
  }
  printf("Size of stub = %d\n", decryptSize);

  // Now start putting data into memory as it will be laid out in
  // the packed executable.

  // Track the # of pieces of initialization data added.
  int numInitData = 0;

  // Store the RVA of the packed code furthest away from the stub.
  *(storageSpot + numInitData++) = (DWORD)baseCodeRVA;
    
  // Store original code entry RVA at storagespot next closest to
  // the stub.
  *(storageSpot + numInitData++) = (DWORD)optionHeader->AddressOfEntryPoint;

  // Store the image base (used with the code base RVA to figure out
  // where the code to unpack is in memory in the unpacker stub) at
  // the next closest spot.
  *(storageSpot + numInitData++) = (DWORD)optionHeader->ImageBase;

  // Store size of code (in bytes) to unpack at the spot closest to
  // the stub.
  *(storageSpot + numInitData++) = virtualCodeSize;

  // Add our decryption routine to storageSpot + (# of data DWORDS
  // added). The +(# of data DWORDS written) is there so that the
  // unpacker stub data added above is not overwritten by the stub.
  //
  // Note that storageSpot is a pointer to a DWORD, so adding 1 to
  // storageSpot advances by 1 DWORD, not 1 BYTE.
  memcpy(storageSpot + numInitData, decryptRoutine, decryptSize);
    
  // Now update the header for the last section (i.e. one with
  // highest RVA) and extend this by size needed and set it to
  // executable.

  // Add the size of the unpacker stub and its initialization data
  // to all of the size tracking fields in the IMAGE_OPTIONAL_HEADER.
  optionHeader->SizeOfImage += 0x2000;
  optionHeader->SizeOfCode += 0x2000;
  optionHeader->SizeOfInitializedData += 0x2000;

  // Set the new initial entry point to the unpacker stub.
  optionHeader->AddressOfEntryPoint = 
    // Start in last section...
    (DWORD)lastSection->VirtualAddress + 
    // At the end of its original data...
    (DWORD)lastSection->SizeOfRawData + 
    // Past the unpacker stub initialization data (4 DWORDs).
    (sizeof(DWORD))*numInitData;

  // Add the size of the unpacker stub and its initialization data
  // to all of the size tracking fields the last section header.
  lastSection->Misc.VirtualSize += 0x2000;
  lastSection->SizeOfRawData += 0x2000;
  lastSection->Characteristics = IMAGE_SCN_MEM_WRITE|
    IMAGE_SCN_MEM_READ|
    IMAGE_SCN_MEM_EXECUTE|
    IMAGE_SCN_CNT_UNINITIALIZED_DATA |
    IMAGE_SCN_CNT_INITIALIZED_DATA|
    IMAGE_SCN_CNT_CODE;//0xE00000E0;

  // Finally we need to set the main code section as writable for
  // our stub to decrypt it. We will do this by making ALL sections
  // writable.
  MakeAllSectionsWritable(firstSectionHeader, 
			  pNTHeader->FileHeader.NumberOfSections); 

  // Close the packed file.
  CloseHandle(hFile);
}