#include "stdafx.h" #include #include #include #include "polymer.h" #include "peutils.h" int SetAES_Passkey(WCHAR *filename, CHAR * pPassKey, CHAR *MARK); int SetASP_Signature(WCHAR * filename, CHAR * signature); int SetCert_Signature(WCHAR * filename, WCHAR * cert); int _tmain(int argc, _TCHAR* argv[]) { HMODULE hMelter = NULL; HANDLE hFile; // PolymerT fPolymer; CHAR szSignature[256]; CHAR szLogPassword[256]; CHAR szConfPassword[256]; WCHAR wsCertFile[MAX_PATH]; WCHAR wsDllFile[MAX_PATH]; WCHAR wsOutFile[MAX_PATH]; if (argc != 7) { printf("ERROR: \n"); printf(" usage: RCSWin32Polymer.exe \n\n"); printf(" is the password for the log encryption\n"); printf(" is the password for the config encryption\n"); printf(" is the customer signature\n"); printf(" is the ASP certificate\n"); printf(" is the dll to be polymerized\n"); printf(" is the output file\n\n"); return 0; } sprintf_s(szLogPassword, sizeof(szLogPassword), "%S", argv[1]); sprintf_s(szConfPassword, sizeof(szConfPassword), "%S", argv[2]); sprintf_s(szSignature, sizeof(szSignature), "%S", argv[3]); wsprintf(wsCertFile, L"%s", argv[4]); wsprintf(wsDllFile, L"%s", argv[5]); wsprintf(wsOutFile, L"%s", argv[6]); /************************************************************************/ /* SANITY CHECKS */ /************************************************************************/ if (strlen(szSignature) < SIGNATURE_LEN) { printf("Signature should be at least %d characters\n", SIGNATURE_LEN); return ERROR_EMBEDDING; } if ( (hFile = CreateFile(wsCertFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, NULL, NULL)) == INVALID_HANDLE_VALUE ) { printf("Cannot find certificate file [%S]\n", wsCertFile); return ERROR_EMBEDDING; } else { DWORD len = GetFileSize(hFile, NULL); if (len < PEM_KEY_LEN) { printf("Bad certificate file len [%S]\n", wsCertFile); return ERROR_EMBEDDING; } CloseHandle(hFile); } #if 0 if ((hMelter = LoadLibrary(POLYMERDLL)) == NULL) { printf("Cannot find the melter dll [%S]\n", POLYMERDLL); return ERROR_NO_MELTER; } if ((fPolymer = (PolymerT) GetProcAddress(hMelter, POLYFUNC)) == NULL) { printf("Cannot find the function in the melter [%S]\n", POLYFUNC); return ERROR_INVALID_MELTER; } #endif /************************************************************************/ /* READY TO GO */ /************************************************************************/ printf("Ready to go...\n"); printf("LOG PASSWORD [%s]\n", szLogPassword); printf("CONF PASSWORD [%s]\n", szConfPassword); printf("SIGNATURE [%s]\n", szSignature); printf("CERTFILE [%S]\n", wsCertFile); printf("INPUT DLL [%S]\n", wsDllFile); printf("OUTPUT DLL [%S]\n\n", wsOutFile); if (CopyFile(wsDllFile, wsOutFile, FALSE) == FALSE) { printf("Cannot create output file[%S]\n", wsOutFile); return ERROR_OUTPUT; } /************************************************************************/ /* BINARY PATCHING */ /************************************************************************/ if (SetAES_Passkey(wsOutFile, szLogPassword, AES_LOG_PASS_MARK) == 0) { printf("Cannot embed log password [%S]\n", wsOutFile); DeleteFile(wsOutFile); return ERROR_EMBEDDING; } else { printf("Log Password embedded... ok\n"); } if (SetAES_Passkey(wsOutFile, szConfPassword, AES_CONF_PASS_MARK) == 0) { printf("Cannot embed conf password [%S]\n", wsOutFile); DeleteFile(wsOutFile); return ERROR_EMBEDDING; } else { printf("Conf Password embedded... ok\n"); } if (SetASP_Signature(wsOutFile, szSignature) == 0) { printf("Cannot embed signature [%S]\n", wsOutFile); DeleteFile(wsOutFile); return ERROR_EMBEDDING; } else { printf("Signature embedded... ok\n"); } if (SetCert_Signature(wsOutFile, wsCertFile) == 0) { printf("Cannot embed pem certificate [%S]\n", wsCertFile); DeleteFile(wsOutFile); return ERROR_EMBEDDING; } else { printf("PEM certificate embedded... ok\n"); } /************************************************************************/ /* POLYMER */ /************************************************************************/ #if 0 try { fPolymer(wsOutFile); } catch (...) { printf("Error while running polymerization\n"); DeleteFile(wsOutFile); return ERROR_POLYMER; } #endif printf("Output file polymerized... ok\n"); #if 0 FreeLibrary(hMelter); #endif return ERROR_SUCCESS; } int SetAES_Passkey(WCHAR *filename, CHAR * pPassKey, CHAR *MARK) { int iRet = false; BYTE * pBlockPtr = NULL; BYTE * pDataSect = NULL; BYTE pPassMd5[32]; unsigned int iLen = 0; pBlockPtr = (BYTE *) LoadPE(filename, &iLen); pDataSect = pBlockPtr; if( pBlockPtr == NULL ) return iRet; __try { while ( pBlockPtr < (pDataSect + iLen) ) { if (!memcmp(pBlockPtr, MARK, AES_MARK_LEN) ) break; else pBlockPtr++; } } __except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ) { pBlockPtr = NULL; } if ( pBlockPtr && (pBlockPtr < ( pDataSect + iLen - 1 )) ) { MD5((unsigned char *) pPassKey, (unsigned long) strlen(pPassKey) , (unsigned char *) pPassMd5); memcpy(pBlockPtr, pPassMd5, 16); iRet = true; } else { iRet = false; } UnloadPE(pBlockPtr); return iRet; } int SetCert_Signature(WCHAR * filename, WCHAR * cert) { int iRet = false; BYTE * pBlockPtr = NULL; BYTE * pDataSect = NULL; BYTE passwd_b[] = PEM_CERT_MARK; FILE *fp = NULL; X509 *req = NULL; unsigned int iLen = 0; pBlockPtr = (BYTE *) LoadPE(filename, &iLen); pDataSect = pBlockPtr; if( pBlockPtr == NULL ) return iRet; __try { while( pBlockPtr < (pDataSect + iLen) ) { if( !memcmp(pBlockPtr,passwd_b, sizeof(passwd_b)) ) break; else pBlockPtr++; } } __except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ) { pBlockPtr = NULL; } if( pBlockPtr && (pBlockPtr <= ( pDataSect + iLen - PEM_KEY_LEN ) ) ) { if((fp = _wfopen(cert, L"r")) == NULL) { UnloadPE(pBlockPtr); return FALSE; } if((req = PEM_read_X509(fp, NULL, NULL, NULL)) == NULL) { fclose(fp); UnloadPE(pBlockPtr); return FALSE; } if(!req->cert_info->key->public_key->data) { X509_free(req); fclose(fp); UnloadPE(pBlockPtr); return FALSE; } memcpy(pBlockPtr, req->cert_info->key->public_key->data, PEM_KEY_LEN); X509_free(req); fclose(fp); iRet = true; } else iRet = false; UnloadPE(pBlockPtr); return iRet; } int SetASP_Signature(WCHAR * filename, CHAR * signature) { int iRet = false; BYTE * pBlockPtr = NULL; BYTE * pDataSect = NULL; BYTE passwd_b[] = SIGNATURE_MARK; BYTE pPassMd5[16]; unsigned int iLen = 0; pBlockPtr = (BYTE *) LoadPE(filename, &iLen); pDataSect = pBlockPtr; if( pBlockPtr == NULL ) return iRet; __try { while( pBlockPtr < (pDataSect + iLen) ) { if( !memcmp(pBlockPtr, passwd_b, sizeof(passwd_b)) ) break; else pBlockPtr++; } } __except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ) { pBlockPtr = NULL; } if( pBlockPtr && (pBlockPtr < ( pDataSect + iLen - SIGNATURE_LEN ) ) ) { MD5((unsigned char *) signature, (unsigned long) strlen(signature) , (unsigned char *) pPassMd5); memcpy(pBlockPtr, pPassMd5, sizeof(pPassMd5)); iRet = true; } else iRet = false; UnloadPE(pBlockPtr); return iRet; } .