////////////////////////////////////////////////////////////////////////////// // // Microsoft Research Singularity // // Copyright (c) Microsoft Corporation. All rights reserved. // // File: smashbin.cpp // // Contents: Smashes two binary files together, with a given offset // Between them padded // #define UNICODE #define _UNICODE #include #include #include #include #include ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// // typedef signed int INT; typedef signed char INT8, *LPINT8; typedef signed short INT16, *LPINT16; typedef unsigned int UINT; typedef unsigned char UINT8, *LPUINT8; typedef unsigned short UINT16, *LPUINT16; BOOL DoPad(HANDLE hOutput, DWORD padSize) { const DWORD nBufferBytes = 0x10000; BYTE bPadBuffer[nBufferBytes]; DWORD nWritten = 0; memset(&bPadBuffer, 0, nBufferBytes); while (padSize > nBufferBytes) { if (0 == WriteFile(hOutput, bPadBuffer, nBufferBytes, &nWritten, NULL)) { fprintf(stderr, "Pad file failed.\n"); return FALSE; } assert(nWritten == nBufferBytes); padSize -= nBufferBytes; } if (padSize > 0) { if (0 == WriteFile(hOutput, bPadBuffer, padSize, &nWritten, NULL)) { fprintf(stderr, "Pad file failed.\n"); return FALSE; } assert(nWritten == padSize); } return TRUE; } BOOL DoCopy(HANDLE hInput, HANDLE hOutput, DWORD * totalWritten) { const DWORD nBufferBytes = 0x10000; BYTE bBuffer[nBufferBytes]; DWORD nRead = 0; do { if (0 == ReadFile(hInput, bBuffer, nBufferBytes, &nRead, NULL)) { fprintf(stderr, "ReadFile failed.\n"); return FALSE; } DWORD nWritten = 0; if (0 == WriteFile(hOutput, bBuffer, nRead, &nWritten, NULL)) { fprintf(stderr, "WriteFile failed.\n"); return FALSE; } assert(nWritten == nRead); (*totalWritten) += nWritten; } while (nRead != 0); return true; } BOOL SmashBins(DWORD offset, PCWSTR bin1, PCWSTR bin2, PCWSTR dest) { BOOL bSuccess = TRUE; DWORD totalWritten = 0; // open output file HANDLE hOutput = CreateFile(dest, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL); if (hOutput == INVALID_HANDLE_VALUE) { fprintf(stderr, "Could not open output file: %ls\n", dest); return false; } // open input 1 HANDLE hInput1 = CreateFile(bin1, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL); if (hInput1 == INVALID_HANDLE_VALUE) { fprintf(stderr, "Could not open image file: %ls\n", bin1); return FALSE; } bSuccess = DoCopy(hInput1, hOutput, &totalWritten); CloseHandle(hInput1); if (!bSuccess) { CloseHandle(hOutput); return bSuccess; } else if (totalWritten > offset) { CloseHandle(hOutput); fprintf(stderr, "First image is larger than offset %d > %d\n", totalWritten, offset); return FALSE; } wprintf(L"00000000..%08x: File %s\n", totalWritten, bin1); bSuccess = DoPad(hOutput, offset - totalWritten); if (!bSuccess) { CloseHandle(hOutput); return bSuccess; } wprintf(L"%08x..%08x: Padding\n", totalWritten, offset); totalWritten += (offset - totalWritten); // open input 2 HANDLE hInput2 = CreateFile(bin2, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL); if (hInput1 == INVALID_HANDLE_VALUE) { fprintf(stderr, "Could not open image file: %ls\n", bin2); return FALSE; } bSuccess = DoCopy(hInput2, hOutput, &totalWritten); wprintf(L"%08x..%08x: File %s\n", offset, totalWritten, bin2); CloseHandle(hInput2); CloseHandle(hOutput); return bSuccess; } int __cdecl wmain(int argc, WCHAR **argv) { BOOL fNeedHelp = FALSE; DWORD offset = 0; int arg; for (arg = 1; arg < argc && !fNeedHelp; arg++) { if (argv[arg][0] != '-' && argv[arg][0] != '/') { break; } WCHAR *argn = argv[arg]+1; // Argument name WCHAR *argp = argn; // Argument parameter while (*argp && *argp != ':') { argp++; } if (*argp == ':') { *argp++ = '\0'; } switch (argn[0]) { case 'o': // Offset int scanfRet; arg++; if(argv[arg][0] == '0' && argv[arg][1] == 'x') { // hex number scanfRet = swscanf(argv[arg], L"%x", &offset); } else { // base 10 number scanfRet = swscanf(argv[arg], L"%d", &offset); } if(EOF == scanfRet) { fNeedHelp = TRUE; } break; case '?': // Help fNeedHelp = TRUE; break; default: printf("Unknown argument: %ls\n", argv[arg]); fNeedHelp = TRUE; break; } } if (fNeedHelp || argc - arg != 3) { printf( "Usage:\n" " mkbin [options] \n" "Options:\n" " /o -- Offset of second binary file\n" " /? -- Display this help screen.\n" "Summary:\n" " Smashes two binaries together, with padding between binaries to provide given offset.\n" ); return 1; } return SmashBins(offset, argv[arg], argv[arg + 1], argv[arg + 2]) ? 0 : 1; } // ///////////////////////////////////////////////////////////////// End of File.