Beispiel #1
0
// -------------------------------------------------------------
// ファイルイメージからメモリイメージを生成する関数
//   引数:pe(PEファイルのヘッダポインタ構造体のポインタ)
//         lpFileImage(ファイルイメージのポインタ)
//         dwMemSize  (メモリイメージのサイズ)
// 戻り値:成功時メモリイメージのポインタ、失敗時NULL
//  備考:プロセスのメモリイメージを格納するためのメモリ領域を
// VirtualAlloc関数にて確保するため、この関数を呼び出したら、そ
// の後FreePEImage関数を呼び出しメモリを開放しなければならない。
// -------------------------------------------------------------
LPVOID LoadPEImage(PPE_HEADERS pe, 
				   LPVOID lpFileImage, 
				   DWORD dwMemSize)
{
	// メモリを確保
	LPVOID lpMemImage = (PTCHAR)VirtualAlloc(
		NULL, dwMemSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
	if(lpMemImage == NULL)
		return NULL;

	PTCHAR szInPtr  = (PTCHAR)lpFileImage;
	PTCHAR szOutPtr = (PTCHAR)lpMemImage;

	// ヘッダをメモリイメージとしてコピー
	DWORD dwHeaderSize = pe->poh->SizeOfHeaders;
	for(int i=0; i < pe->pfh->NumberOfSections; i++){
		if(pe->psh[i].PointerToRawData < dwHeaderSize)
			dwHeaderSize = pe->psh[i].PointerToRawData;
	}
	CopyMemory(szOutPtr, szInPtr, dwHeaderSize);

	// ポインタ移動
	szOutPtr += GetAlignedSize(
		pe->poh->SizeOfHeaders, pe->poh->SectionAlignment);
	
	// 全セクションをメモリイメージとしてコピー
	for(int i=0; i < pe->pfh->NumberOfSections; i++){
		
		// セクションサイズが0以下ならば無視
		if(pe->psh[i].SizeOfRawData <= 0){
			// もしVirtualSizeがあるなら更新
			if(pe->psh[i].Misc.VirtualSize){
				szInPtr += GetAlignedSize(
					pe->psh[i].Misc.VirtualSize, 
					pe->poh->SectionAlignment);
			}
			continue;
		}
		
		// セクションの読み込みサイズを取得
		DWORD dwToRead = pe->psh[i].SizeOfRawData;
		if(dwToRead > pe->psh[i].Misc.VirtualSize)
			dwToRead = pe->psh[i].Misc.VirtualSize;

		// 1セクションをメモリイメージとしてコピー
		szInPtr = (PTCHAR)lpFileImage + pe->psh[i].PointerToRawData;
		CopyMemory(szOutPtr, szInPtr, dwToRead);
		
		// ポインタ移動
		szOutPtr += GetAlignedSize(
			pe->psh[i].Misc.VirtualSize, pe->poh->SectionAlignment);
	}

	// メモリポインタを返す
	return lpMemImage;
}
Beispiel #2
0
// -------------------------------------------------------------
// メモリイメージのサイズを計算する関数
//   引数:pe(PEファイルのヘッダポインタ構造体のポインタ)
// 戻り値:メモリイメージのサイズ
// -------------------------------------------------------------
DWORD TotalNewImageSize(PPE_HEADERS pe)
{
	// ヘッダのサイズを代入
	DWORD dwRet = GetAlignedSize(
		pe->poh->SizeOfHeaders, pe->poh->SectionAlignment);

	// セクションごとのサイズを加算
	for(int i=0; i < pe->pfh->NumberOfSections; i++){
		if( ! pe->psh[i].Misc.VirtualSize)
			continue;
		dwRet += GetAlignedSize(
			pe->psh[i].Misc.VirtualSize, pe->poh->SectionAlignment);
	}

	// PEファイルのイメージサイズを返す
	return dwRet;
}
Beispiel #3
0
// 计算加载pe并对齐需要占用多少内存   
// 未直接使用OptionalHeader.SizeOfImage作为结果是因为据说有的编译器生成的exe这个值会填0   
unsigned long CExeMemory::CalcTotalImageSize(PIMAGE_DOS_HEADER MzH, unsigned long FileLen, PIMAGE_NT_HEADERS peH, PIMAGE_SECTION_HEADERS peSecH)   
{   
    unsigned long res;   
    // 计算pe头的大小   
    res = GetAlignedSize( peH->OptionalHeader.SizeOfHeaders   
        , peH->OptionalHeader.SectionAlignment   
        );   
  
    // 计算所有节的大小   
    for( int i = 0; i < peH->FileHeader.NumberOfSections; ++i)   
    {   
        // 超出文件范围   
        if(peSecH[i]->PointerToRawData + peSecH[i]->SizeOfRawData > FileLen)   
            return 0;   
        else if(peSecH[i]->VirtualAddress)//计算对齐后某节的大小   
        {   
            if(peSecH[i]->Misc.VirtualSize)   
            {   
                res = GetAlignedSize( peSecH[i]->VirtualAddress + peSecH[i]->Misc.VirtualSize   
                    , peH->OptionalHeader.SectionAlignment   
                    );   
            }   
            else  
            {   
                res = GetAlignedSize( peSecH[i]->VirtualAddress + peSecH[i]->SizeOfRawData   
                    , peH->OptionalHeader.SectionAlignment   
                    );   
            }   
        }   
        else if( peSecH[i]->Misc.VirtualSize < peSecH[i]->SizeOfRawData )   
        {   
            res += GetAlignedSize( peSecH[i]->SizeOfRawData   
                , peH->OptionalHeader.SectionAlignment   
                );   
        }   
        else  
        {   
            res += GetAlignedSize( peSecH[i]->Misc.VirtualSize   
                , peH->OptionalHeader.SectionAlignment   
                );   
        }// if_else   
    }// for   
       
    return res;   
}   
Beispiel #4
0
/**
    @brief Receive message from the server
    @param size - return size of data
    @param decrypt - if TRUE, then decrypt received data by session key
    @param control - return control character
    @return data (you MUST free memory after use)
*/
byte *tcpReceiveMessage(int Handle, uint32 *size, byte *control, uint32 TimeoutMsec)
{
	StreamMethod Method = smRecvSend;
	byte *data;
	int ret = 0;
	byte cc = 0;
	byte LengthField[MAXLENGTHFIELDSIZE];
	byte LengthFieldSize;
	uint32 AlignedSize;
	byte AttempsCount = 1;
	byte MaxAttempsCount = 5;
lblWaitAgain:
	*size = 0;
	*control = 0;
	data = NULL;
	sleepms(100);
	ret = recvByte(Handle, Method, &cc, 0/*Timeout*/);
	//printf"recvByte: %d. byte %d\n", ret, cc);
	if (ret > 0)
	{
		*control = cc;
		switch (cc)
		{
			case pccSTX:
				*size = ReceiveLengthField(Handle, Method, LengthField, &LengthFieldSize, TimeoutMsec); // получаем размер данных
				if (*size != 0xFFFFFFFF)
				{
					AlignedSize = GetAlignedSize(*size);
					data = malloc(AlignedSize); // allocate data
					ret = recvBuffer(Handle, Method, data, AlignedSize, TimeoutMsec);
					#ifdef TCP_DEBUG
						// PrintHEX(data, *size);
					#endif
					//printf"comRecvBufLarge: %d\n", ret);
					if (ret > 0)
					{
						// ok, we have a data - calc CRC
						uint32 CRCBufferSize = LengthFieldSize + AlignedSize + 1; // datasize + data + ETX
						byte *CRCBuffer = malloc(CRCBufferSize);
						memcpy(CRCBuffer, LengthField, LengthFieldSize); // copy length field to checkbuffer
						memcpy(CRCBuffer+LengthFieldSize, data, AlignedSize); // copy data from checkbuffer
						CRCBuffer[CRCBufferSize - 1] = pccETX; // last character = ETX
						uint64 CalculatedCRC = crcCalculate(CRCBuffer, CRCBufferSize);

						free(CRCBuffer);
						CRCBuffer = NULL;

						ret = recvByte(Handle, Method, &cc, TimeoutMsec); // receive ETX character
						//printf"comRecv: %d. byte %d\n", ret, cc);
						if (ret > 0 && cc == pccETX)
						{
							byte crcfield[crcGetFieldSize(CRCBufferSize)];
							ret = recvBuffer(Handle, Method, crcfield, sizeof(crcfield), TimeoutMsec); // get size
							uint64 ReceivedCRC = crcExtract(crcfield, sizeof(crcfield));
							//printf"comRecvBuf: %d\n", ret);
							if (ret > 0)
							{
								if (ReceivedCRC == CalculatedCRC)	// check the data
									ret = sendByte(Handle, Method, pccACK); // good!!!
								else
								{
				    				if (AttempsCount <= MaxAttempsCount)
				    				{
				    					AttempsCount++;
				    					ret = sendByte(Handle, Method, pccNAK);
										// and go to wait this packet again
										goto lblWaitAgain;
				    				}
				    				else
				    				{ free(data); data = NULL; }
								}
							}
							else
							{ free(data); data = NULL; }
						}
						else
						{ free(data); data = NULL; }
					}
					else
					{ free(data); data = NULL; }
				}
				break;
			case pccEOT: // query close connection
				data = NULL;
				break;
			case pccBEL:
				sendByte(Handle, Method, pccBEL);
				goto lblWaitAgain;
			default:
				data = NULL;
				break;
		}
	}
	else
	{
		*control = 0;
		data = NULL;
	}

	/*if (data)
		cphDecrypt(data, data, PCSessionKey, AlignedSize, ToServer); // decipher received data*/

	return data;
}
Beispiel #5
0
/**
    @brief Send message to the server (PC or Retail system)
    @param size - return size of data
    @param decrypt - if TRUE, then decrypt received data by session key
    @param control - return control character
    @return TRUE if OK, or error code
*/
Bool tcpSendMessage(int Handle, byte *Data, uint32 DataSize, uint32 TimeoutMSec)
{
	StreamMethod Method = smRecvSend;
	int ret;
	Bool result = FALSE;
	uint32 size = DataSize;
	uint32 AlignedSize = GetAlignedSize(size);
	byte LengthField[MAXLENGTHFIELDSIZE];
	byte LengthFieldSize;
	tlvMakeLengthField(size, LengthField, &LengthFieldSize);
	byte MaxAttempsCount = 5;
	byte ack;

	tBuffer sendbuf;
	byte DataToSend[AlignedSize + MAXLENGTHFIELDSIZE + 1 + MAXCRCBUFFERSIZE]; // + max data size buffer, ETX, max CRC buffer
	bufInit(&sendbuf, DataToSend, sizeof(DataToSend)); // init buffer for writing (and clear of DataToSend)
	bufApp(&sendbuf, LengthField, LengthFieldSize);

	memcpy(DataToSend + sendbuf.pos, Data, DataSize); // просто копирование, без шифрования

	sendbuf.pos += AlignedSize; // DataToSend уже лежит в буфере на отправку
	bufAppByte(&sendbuf, pccETX); // append ETX to buffer
	byte CRCBuffer[MAXCRCBUFFERSIZE];
	byte CRCBufferSize = crcMakeField(sendbuf.ptr, (word)sendbuf.pos, CRCBuffer);
	bufApp(&sendbuf, CRCBuffer, CRCBufferSize);
	/*
	printf("CRC Buffer: ");
	PrintHEX(CRCBuffer, CRCBufferSize);*/

	byte AttempsCount = 1;
lblSendAgain:
    ret = sendByte(Handle, Method, pccSTX); // send control char "start of packet"
    if (ret > 0)
    {
    	ret = sendBuffer(Handle, Method, bufPtr(&sendbuf), bufLen(&sendbuf)); // send packet
  		if (ret == bufLen(&sendbuf))
    	{
    		// and wait for acknowledgment
    	lblWaitAskAgain:
    		ack = 0;
    		ret = recvByte(Handle, Method, &ack, TimeoutMSec);
    		if (ret > 0)
    		{
        		switch (ack)
        		{
    				case pccACK: // good
    					result = TRUE;
    					break;
    				case pccBEL: // please, wait
    					sendByte(Handle, Method, pccBEL);
    					goto lblWaitAskAgain;
    				case pccNAK: // send packet again
        				if (AttempsCount <= MaxAttempsCount)
        				{
        					AttempsCount++;
        					goto lblSendAgain;
        				}
        				else
    						result = FALSE;
        				break;
    				default: // unknown state
    					result = FALSE;
    					break;
        		}
    		}
    		else
    			result = FALSE;
    	}
		else
			result = FALSE;
    }
	else
		result = FALSE;
    //ptarr = memFree(ptarr);
	return result;
}
Beispiel #6
0
// 加载pe到内存并对齐所有节   
BOOL CExeMemory::AlignPEToMem( void *Buf, long Len, PIMAGE_NT_HEADERS &peH, PIMAGE_SECTION_HEADERS &peSecH, void *&Mem, unsigned long &ImageSize)   
{   
    PIMAGE_DOS_HEADER SrcMz;// DOS头   
    PIMAGE_NT_HEADERS SrcPeH;// PE头   
    PIMAGE_SECTION_HEADERS SrcPeSecH;// 节表   
       
    SrcMz = (PIMAGE_DOS_HEADER)Buf;   
  
    if( Len < sizeof(IMAGE_DOS_HEADER) )    
        return FALSE;   
       
    if( SrcMz->e_magic != IMAGE_DOS_SIGNATURE )   
        return FALSE;   
       
    if( Len < SrcMz->e_lfanew + (long)sizeof(IMAGE_NT_HEADERS) )   
        return FALSE;   
  
    SrcPeH = (PIMAGE_NT_HEADERS)((int)SrcMz + SrcMz->e_lfanew);   
    if( SrcPeH->Signature != IMAGE_NT_SIGNATURE )   
        return FALSE;   
  
    if( (SrcPeH->FileHeader.Characteristics & IMAGE_FILE_DLL) ||   
        (SrcPeH->FileHeader.Characteristics & IMAGE_FILE_EXECUTABLE_IMAGE == 0) ||   
        (SrcPeH->FileHeader.SizeOfOptionalHeader != sizeof(IMAGE_OPTIONAL_HEADER)) )   
    {   
        return FALSE;   
    }   
  
  
    SrcPeSecH = (PIMAGE_SECTION_HEADERS)((int)SrcPeH + sizeof(IMAGE_NT_HEADERS));   
    ImageSize = CalcTotalImageSize( SrcMz, Len, SrcPeH, SrcPeSecH);   
  
    if( ImageSize == 0 )   
        return FALSE;   
       
    Mem = VirtualAlloc( NULL, ImageSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE); // 分配内存   
    if( Mem != NULL )   
    {   
        // 计算需要复制的PE头字节数   
        unsigned long l = SrcPeH->OptionalHeader.SizeOfHeaders;   
        for( int i = 0; i < SrcPeH->FileHeader.NumberOfSections; ++i)   
        {   
            if( (SrcPeSecH[i]->PointerToRawData) &&   
                (SrcPeSecH[i]->PointerToRawData < l) )   
            {   
                l = SrcPeSecH[i]->PointerToRawData;   
            }   
        }   
        memmove( Mem, SrcMz, l);   
        peH = (PIMAGE_NT_HEADERS)((int)Mem + ((PIMAGE_DOS_HEADER)Mem)->e_lfanew);   
        peSecH = (PIMAGE_SECTION_HEADERS)((int)peH + sizeof(IMAGE_NT_HEADERS));   
  
        void *Pt = (void *)((unsigned long)Mem    
            + GetAlignedSize( peH->OptionalHeader.SizeOfHeaders   
            , peH->OptionalHeader.SectionAlignment)   
            );   
  
        for( int i = 0; i < peH->FileHeader.NumberOfSections; ++i)   
        {   
            // 定位该节在内存中的位置   
            if(peSecH[i]->VirtualAddress)   
                Pt = (void *)((unsigned long)Mem + peSecH[i]->VirtualAddress);   
  
            if(peSecH[i]->SizeOfRawData)   
            {   
                // 复制数据到内存   
                memmove(Pt, (const void *)((unsigned long)(SrcMz) + peSecH[i]->PointerToRawData), peSecH[i]->SizeOfRawData);   
                if(peSecH[i]->Misc.VirtualSize < peSecH[i]->SizeOfRawData)   
                    Pt = (void *)((unsigned long)Pt + GetAlignedSize(peSecH[i]->SizeOfRawData, peH->OptionalHeader.SectionAlignment));   
                else // pt 定位到下一节开始位置   
                    Pt = (void *)((unsigned long)Pt + GetAlignedSize(peSecH[i]->Misc.VirtualSize, peH->OptionalHeader.SectionAlignment));   
            }   
            else  
            {   
                Pt = (void *)((unsigned long)Pt + GetAlignedSize(peSecH[i]->Misc.VirtualSize, peH->OptionalHeader.SectionAlignment));   
            }   
        }   
    }   
    return TRUE;   
}