Commit 7b0a7468 by 刘帅

工程中加入验签(自验)

parent a7de2ce8
......@@ -16,8 +16,9 @@ LIBS += -lfmcrypt
LIBS += -L$$PWD/out32dll
INCLUDEPATH += $$PWD/openssl
INCLUDEPATH += ./encrypt
INCLUDEPATH += ./gtest
INCLUDEPATH += ./encrypt \
$$PWD/gtest \
$$PWD/base
include(./QsLog/QsLog.pri)
......@@ -33,7 +34,11 @@ SOURCES += main.cpp\
widget.cpp \
qfmclient.cpp \
scanner.cpp \
encrypt/encrypt.cpp
encrypt/encrypt.cpp \
base/FmPee.cpp \
base/FPe.cpp \
base/md5.cpp \
verifysign.cpp
HEADERS += widget.h \
fmcrypt.h \
......@@ -45,7 +50,12 @@ HEADERS += widget.h \
encrypt/encrypt.h \
qfmclient_test.h \
encrypt/encrypt_test.h \
app_single_test.h
app_single_test.h \
base/FmPee.h \
base/FPe.h \
base/md5.h \
verifysign.h \
verifysign_test.h
FORMS += widget.ui \
scanner.ui
......
#include"FPe.h"
#include "FmPee.h"
#include "md5.h"
#include <string>
#include <fstream>
namespace FPE{
BOOL IsMy=FALSE;
void SetMy(BOOL b)
{
IsMy = b;
}
BOOL IsPeFile(IN void *lpFileModule)
{
PIMAGE_DOS_HEADER l_lpstDosHeader;
PIMAGE_NT_HEADERS l_lpstNtHeaders;
l_lpstDosHeader = (PIMAGE_DOS_HEADER)lpFileModule;
if (l_lpstDosHeader->e_magic == IMAGE_DOS_SIGNATURE)
{
l_lpstNtHeaders = (PIMAGE_NT_HEADERS)((UINT)lpFileModule + l_lpstDosHeader->e_lfanew);
if (l_lpstNtHeaders->Signature == IMAGE_NT_SIGNATURE)
return TRUE;
}
return FALSE;
}
HANDLE MyCreateFile(IN char *lpszFileName,UINT uOpenFlag)
{
if (!IsMy)
{
return CreateFileA(lpszFileName,
GENERIC_READ |GENERIC_WRITE,
FILE_SHARE_READ,
NULL,
uOpenFlag,
0,
NULL);
}else{
return CreateFileA(lpszFileName,
GENERIC_READ,
FILE_SHARE_READ,
NULL,
uOpenFlag,
0,
NULL);
}
}
HANDLE MyCreateMapFile(IN HANDLE hFile)
{
if (!FPE::IsMy)
{
return CreateFileMapping(hFile,NULL,PAGE_READWRITE,0,0,NULL);
}else{
return CreateFileMapping(hFile,NULL,PAGE_READONLY,0,0,NULL);
}
}
ULONG MyReadFile(IN HANDLE hFile,OUT void *lpBuff,IN int nNumToRead)
{
ULONG nNumOfRead = 0;
if (ReadFile(hFile,lpBuff,nNumToRead,&nNumOfRead,NULL))
return nNumOfRead;
return 0;
}
ULONG MyWriteFile(IN HANDLE hFile,IN void *lpBuff,IN int nNumToWrite)
{
ULONG nNumOfWrite;
if (WriteFile(hFile,lpBuff,nNumToWrite,&nNumOfWrite,NULL))
return nNumOfWrite;
return 0;
}
void *MyMapViewOfFile(IN HANDLE hMap)
{
if (!FPE::IsMy)
{
return MapViewOfFile(hMap,FILE_MAP_READ | FILE_MAP_WRITE,0,0,0);
}else{
return MapViewOfFile(hMap,FILE_MAP_READ,0,0,0);
}
}
BOOL IsFiles(IN char *lpszFileName)
{
HANDLE l_hFile;
HANDLE l_hMap;
void *l_lpFileBuff;
char l_szMsgBuff[CHAR_MAX];
ZeroMemory(&l_szMsgBuff,sizeof(l_szMsgBuff));
l_hFile = MyCreateFile(lpszFileName,OPEN_EXISTING);
if (l_hFile == INVALID_HANDLE_VALUE)
{
//wsprintf(l_szMsgBuff,"打开%s文件出错!!\r\n",lpszFileName);
return FALSE;
}
l_hMap = MyCreateMapFile(l_hFile);
if (!l_hMap)
{
//AfxMessageBox("打开文件映射出错");
CloseHandle(l_hFile);
return FALSE;
}
l_lpFileBuff = MyMapViewOfFile(l_hMap);
if (!l_lpFileBuff)
{
//AfxMessageBox("打开文件映射缓冲出错");
CloseHandle(l_hMap);
CloseHandle(l_hFile);
return FALSE;
}
if (IsPeFile(l_lpFileBuff))
{
ZeroMemory(&l_szMsgBuff,sizeof(l_szMsgBuff));
//wsprintf(l_szMsgBuff,"%s是有效的PE文件!\r\n",lpszFileName);
//AfxMessageBox(l_szMsgBuff);
}else
{
ZeroMemory(&l_szMsgBuff,sizeof(l_szMsgBuff));
//wsprintf(l_szMsgBuff,"%s不是一个PE文件!\r\n",lpszFileName);
//AfxMessageBox(l_szMsgBuff);
}
UnmapViewOfFile(l_lpFileBuff);
CloseHandle(l_hMap);
CloseHandle(l_hFile);
return TRUE;
}
void *GetPeOverlay(IN void *lpPeBuff)
{
PIMAGE_DOS_HEADER l_lpstDosHeader;
PIMAGE_NT_HEADERS l_lpstNtHeaders;
PIMAGE_SECTION_HEADER l_lpstSecHeader;
int l_uSecSize;
l_lpstDosHeader = (PIMAGE_DOS_HEADER)lpPeBuff;
l_lpstNtHeaders = (PIMAGE_NT_HEADERS)((UINT)lpPeBuff + l_lpstDosHeader->e_lfanew);
l_lpstSecHeader = (PIMAGE_SECTION_HEADER)((UINT)l_lpstNtHeaders + sizeof(IMAGE_NT_HEADERS));
l_uSecSize = l_lpstNtHeaders->FileHeader.NumberOfSections;
l_lpstSecHeader = (PIMAGE_SECTION_HEADER)((UINT)l_lpstSecHeader + (sizeof(IMAGE_SECTION_HEADER) * (l_uSecSize-1)));
return (void *)((UINT)lpPeBuff + (l_lpstSecHeader->PointerToRawData + l_lpstSecHeader->SizeOfRawData));
}
BOOL ReadWriteDate(IN char *lpszPatchFileName, IN char* wbuffer)
{
HANDLE l_hPatchFile,l_hPatchMap;
void *l_lpPatchBuff;
char l_szMsgBuff[CHAR_MAX];
int l_uFileSize;
BOOL l_bIsWrite = FALSE;
//if (IsFiles(lpszPatchFileName))
{
//开始添加EXE尾部附加数据
ZeroMemory(&l_szMsgBuff,sizeof(l_szMsgBuff));
//正在打开文件
l_hPatchFile = MyCreateFile(lpszPatchFileName,OPEN_EXISTING);
if (l_hPatchFile == INVALID_HANDLE_VALUE)
{
ZeroMemory(&l_szMsgBuff,sizeof(l_szMsgBuff));
//wsprintf(l_szMsgBuff,"错误!无法打开%s文件!!\r\n",lpszPatchFileName);
//AfxMessageBox(l_szMsgBuff);
return FALSE;
}
l_uFileSize = GetFileSize(l_hPatchFile,NULL);
l_hPatchMap = MyCreateMapFile(l_hPatchFile);
if (l_hPatchMap)
{
l_lpPatchBuff = MyMapViewOfFile(l_hPatchMap);
if (l_lpPatchBuff)
{
if (!IsPeFile(l_lpPatchBuff))
{
ZeroMemory(&l_szMsgBuff,sizeof(l_szMsgBuff));
//wsprintf(l_szMsgBuff,"错误!%s文件必须是PE文件!!\r\n",lpszPatchFileName);
UnmapViewOfFile(l_lpPatchBuff);
CloseHandle(l_hPatchMap);
CloseHandle(l_hPatchFile);
return FALSE;
}
if ((int)GetPeOverlay(l_lpPatchBuff) - (int)l_lpPatchBuff != l_uFileSize)
{
int ilen1=(int)GetPeOverlay(l_lpPatchBuff);
int ilen2=(int)l_lpPatchBuff;
int ilen3=ilen1-ilen2;
int iKeySize=l_uFileSize-ilen3;
//存在尾部数据,则读取尾部数据
//char buf[512]={0};
SetFilePointer(l_hPatchFile,l_uFileSize-iKeySize,0,NULL);
//ReadFile(l_hPatchFile,buf,iKeySize,NULL,NULL);
MyReadFile(l_hPatchFile,wbuffer,iKeySize);
CloseHandle(l_hPatchMap);
CloseHandle(l_hPatchFile);
return true;
}
UnmapViewOfFile(l_lpPatchBuff);
}
}else
{
ZeroMemory(&l_szMsgBuff,sizeof(l_szMsgBuff));
//wsprintf(l_szMsgBuff,"错误!无法创建%s文件映像!!\r\n",lpszPatchFileName);
CloseHandle(l_hPatchFile);
return FALSE;
}
if (strlen(wbuffer) > 0)
{
SetFilePointer(l_hPatchFile,0,0,FILE_END);
char buf[512]={0};
memcpy(buf,wbuffer,strlen(wbuffer));
if (MyWriteFile(l_hPatchFile,buf,strlen(buf)))
l_bIsWrite = TRUE;
}
CloseHandle(l_hPatchMap);
CloseHandle(l_hPatchFile);
}
return l_bIsWrite;
}
BOOL WriteData(IN char *lpszPatchFileName,IN char* wbuf)
{
return ReadWriteDate(lpszPatchFileName, wbuf);
}
std::string ReadDate(IN char *lpszPatchFileName)
{
char buf[512]={0};
ReadWriteDate(lpszPatchFileName, buf);
return buf;
}
}
#include <string>
#include "Windows.h"
using namespace std;
namespace FPE{
void SetMy(BOOL b);
BOOL WriteData(IN char *lpszPatchFileName,IN char* wbuf);
std::string ReadDate(IN char *lpszPatchFileName);
}
#include "FmPee.h"
#include "md5.h"
#include <string>
#include <fstream>
namespace FmMd5{
std::string FileDigest(std::string file) {
ifstream in(file.c_str(), ios::binary);
if (!in) {
return "";
}
MD5 md5;
std::streamsize length;
char buffer[1024];
while (!in.eof()) {
in.read(buffer, 1024);
length = in.gcount();
if (length > 0) {
md5.update(buffer, length);
}
}
in.close();
md5.finalize();
std::string tempstr=md5.hexdigest();
return tempstr.c_str();
}
std::string FileDigest(std::string file,int minusCount) {
ifstream in(file.c_str(), ios::binary);
if (!in) {
return "";
}
in.seekg(0, ios_base::end);
int nFileLen = in.tellg();
double iCount=ceil((double)nFileLen/1024);
iCount=iCount-minusCount;
if (iCount <= minusCount)
{
return "";
}
MD5 md5;
std::streamsize length;
char buffer[1024];
int i=0;
while (!in.eof()) {
i++;
in.read(buffer, 1024);
length = in.gcount();
if (length > 0) {
md5.update(buffer, length);
}
if (i == iCount)
{
md5.update(buffer, length);
}
}
in.close();
md5.finalize();
std::string tempstr=md5.hexdigest();
return tempstr.c_str();
}
}
namespace FmPeeEncrypt{
std::string FmEncryptKey(std::string sourcestr, std::string time)
{
std::string encryptstr="";
if (time.length() == 8)
{
int ii=0;
for (int i=0;i<8;i++)
{
ii += atoi(time.substr(i,1).c_str());
}
int iunit=ii/1%10;
std::string key;
char keybuf[10]={0};
sprintf(keybuf,"%s%d",time.c_str(),iunit);
key=keybuf;
for (int i=0;i<9;i++)
{
int index= atoi(key.substr(i,1).c_str());
encryptstr +=sourcestr.c_str()[index];
}
//最后拼接3位数
encryptstr+=sourcestr.substr(29,3);
//计算md5
MD5 md5(encryptstr);
encryptstr=md5.hexdigest();
}
return encryptstr;
}
}
#include <string>
using namespace std;
namespace FmMd5{
std::string FileDigest(std::string file);
std::string FileDigest(std::string file,int minusCount);
}
namespace FmPeeEncrypt{
std::string FmEncryptKey(std::string sourcestr, std::string time);
}
\ No newline at end of file
This diff is collapsed. Click to expand it.
/* MD5
converted to C++ class by Frank Thilo (thilo@unix-ag.org)
for bzflag (http://www.bzflag.org)
based on:
md5.h and md5.c
reference implementation of RFC 1321
Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
rights reserved.
License to copy and use this software is granted provided that it
is identified as the "RSA Data Security, Inc. MD5 Message-Digest
Algorithm" in all material mentioning or referencing this software
or this function.
License is also granted to make and use derivative works provided
that such works are identified as "derived from the RSA Data
Security, Inc. MD5 Message-Digest Algorithm" in all material
mentioning or referencing the derived work.
RSA Data Security, Inc. makes no representations concerning either
the merchantability of this software or the suitability of this
software for any particular purpose. It is provided "as is"
without express or implied warranty of any kind.
These notices must be retained in any copies of any part of this
documentation and/or software.
*/
#ifndef BZF_MD5_H
#define BZF_MD5_H
#include <string>
#include <iostream>
// a small class for calculating MD5 hashes of strings or byte arrays
// it is not meant to be fast or secure
//
// usage: 1) feed it blocks of uchars with update()
// 2) finalize()
// 3) get hexdigest() string
// or
// MD5(std::string).hexdigest()
//
// assumes that char is 8 bit and int is 32 bit
class MD5
{
public:
typedef unsigned int size_type; // must be 32bit
MD5();
MD5(const std::string& text);
void update(const unsigned char *buf, size_type length);
void update(const char *buf, size_type length);
MD5& finalize();
std::string hexdigest() const;
std::string md5() const;
friend std::ostream& operator<<(std::ostream&, MD5 md5);
private:
void init();
typedef unsigned char uint1; // 8bit
typedef unsigned int uint4; // 32bit
enum {blocksize = 64}; // VC6 won't eat a const static int here
void transform(const uint1 block[blocksize]);
static void decode(uint4 output[], const uint1 input[], size_type len);
static void encode(uint1 output[], const uint4 input[], size_type len);
bool finalized;
uint1 buffer[blocksize]; // bytes that didn't fit in last 64 byte chunk
uint4 count[2]; // 64bit counter for number of bits (lo, hi)
uint4 state[4]; // digest so far
uint1 digest[16]; // the result
// low level logic operations
static inline uint4 F(uint4 x, uint4 y, uint4 z);
static inline uint4 G(uint4 x, uint4 y, uint4 z);
static inline uint4 H(uint4 x, uint4 y, uint4 z);
static inline uint4 I(uint4 x, uint4 y, uint4 z);
static inline uint4 rotate_left(uint4 x, int n);
static inline void FF(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac);
static inline void GG(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac);
static inline void HH(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac);
static inline void II(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac);
};
#endif
......@@ -3,12 +3,14 @@
#include "qfmclient.h"
#include "app_single.h"
#include "log.h"
#include "verifysign.h"
#include "base/FPe.h"
#include "scanner.h"
#include "gtest/gtest.h"
#include "qfmclient_test.h"
#include "encrypt/encrypt_test.h"
#include "app_single_test.h"
#include "verifysign_test.h"
#ifdef QT_DEBUG
#pragma comment (lib, "gtestd.lib")
......@@ -29,6 +31,16 @@ int main(int argc, char *argv[])
OutputDebugString(L"FmclientUi running.");
return 0;
}
QString filePath = QCoreApplication::applicationFilePath();
FPE::SetMy(TRUE);
std::string rData = FPE::ReadDate((char*)filePath.toStdString().c_str());
if(!VerifySign(filePath.toStdString(), rData))
{
qDebug() << "verify failed! this application can not run.";
return 0;
}
InitLogger();
QLOG_INFO()<<"start FmclientUi...";
Widget w;
......
#include"verifysign.h"
#include"base/FmPee.h"
bool VerifySign(std::string filepath,std::string encryptstr)
{
if (encryptstr.find("|") != -1)
{
//计算局部md5
std:string md5str=FmMd5::FileDigest(filepath.c_str(),2).c_str();
std::string g_filemd5="";//局部md5
std::string g_date=""; //日期
std::string g_sign=""; //签名
{
int iRet1=encryptstr.find("|");
if (iRet1 != -1)
{
g_filemd5=encryptstr.substr(0,iRet1);
std::string tempstr=encryptstr.substr(iRet1+1,encryptstr.length());
int iRet2=tempstr.find("|");
if (iRet2 != -1)
{
g_date=tempstr.substr(0,iRet2);
g_sign=tempstr.substr(iRet2+1,tempstr.length());
}
}
}
if (g_filemd5.length()==0 || g_date.length()==0 || g_sign.length() == 0)
{
return false;
}
//加密
std::string signstr=FmPeeEncrypt::FmEncryptKey(md5str.c_str(),g_date.c_str()).c_str();
//比较字符串
if (memcmp(md5str.c_str(),g_filemd5.c_str(),32)==0 && memcmp(signstr.c_str(),g_sign.c_str(),32)==0)
{
return true;
}
}
return false;
}
#ifndef VERIFYSIGN
#define VERIFYSIGN
#include <string>
bool VerifySign(std::string filepath,std::string encryptstr);
#endif // VERIFYSIGN
#ifndef VERIFYSIGN_TEST_H
#define VERIFYSIGN_TEST_H
#include "gtest/gtest.h"
#include "verifysign.h"
TEST(verify, sign)
{
FPE::SetMy(TRUE);
QString filePath = QCoreApplication::applicationFilePath();
std::string rData = FPE::ReadDate((char*)filePath.toStdString().c_str());
EXPECT_EQ(false, VerifySign(filePath.toStdString(), rData));
}
#endif // VERIFYSIGN_TEST_H
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment