一、实现功能头文件:AnalysisIniFile.h
#ifndef __ANALYSISINIFILE_H__
#define __ANALYSISINIFILE_H__
#include <windows.h>
#include <stdio.h>
#define BUFFER_SIZE 256
#define MAX_IP_STRING_LEN 100
#define PATCH_OFFSET 5
#define PATCH_SIZE 7
#define LONG_JUMP 0xE9 //指令码
#define SHORT_JUMP 0xEB //指令码
#define SHORTJUMP_ADDRESS 0xF9 //地址码
#define LONGJUMP_OFFSET 0
#define SHORTJUMP_OFFSET 5
#define ADDRESS_OFFSET 1
#define RETURN_ERR 0
#define RETURN_OK 1
#define snprintf _snprintf
typedef DWORD (WINAPI *FUN_PTR)(LPCSTR,LPCSTR,LPCSTR,LPSTR,DWORD,LPCSTR);
DWORD WINAPI EML_GetPrivateProfileString(LPCSTR lpAppName,LPCSTR lpKeyName,LPCSTR lpDefault,LPSTR lpReturnedString,DWORD nSize,LPCSTR lpFileName);
UINT WINAPI EML_GetPrivateProfileInt(LPCSTR lpAppName, LPCSTR lpKeyName, INT nDefault, LPCSTR lpFileName);
BOOL HotPatchWin32API(FUN_PTR pfnOld, FUN_PTR pfnNew);
#endif
二、源文件:AnalysisIniFile.c
/******************************************************************************
文 件 名 : AnalysisIniFile.c
版 本 号 : 初稿
作 者 :
生成日期 : 2013年11月18日
最近修改 :
功能描述 : 通过HOOK系统的API接口实现对API功能的修改
函数列表 :
修改历史 :
1.日 期 : 2013年11月18日
作 者 :
修改内容 : 创建文件
******************************************************************************/
#include "AnalysisIniFile.h"
/*****************************************************************************
函 数 名 : EML_GetPrivateProfileInt
功能描述 : 解析ini文件字段,int类型
输入参数 : LPCSTR lpAppName,
LPCSTR lpKeyName,
INT nDefault,
LPCSTR lpFileName
输出参数 : 无
返 回 值 : 数字型键值
调用函数 :
被调函数 :
修改历史 :
1.日 期 : 2013年11月20日
作 者 :
修改内容 : 新生成函数
*****************************************************************************/
UINT WINAPI EML_GetPrivateProfileInt(
__in LPCSTR lpAppName,
__in LPCSTR lpKeyName,
__in INT nDefault,
__in_opt LPCSTR lpFileName)
{
CHAR szKeyValue[BUFFER_SIZE] = {0};
UINT uiKeyValue = nDefault;
DWORD dwResult = 0;
dwResult = EML_GetPrivateProfileString(lpAppName, lpKeyName, "0", szKeyValue, sizeof(szKeyValue), lpFileName);
if (dwResult <= 0)
{
return 0;
}
uiKeyValue = atoi(szKeyValue);
return uiKeyValue;
}
/*****************************************************************************
函 数 名 : EML_GetPrivateProfileString
功能描述 : 解析ini文件字段,String类型
输入参数 : LPCSTR lpAppName,
LPCSTR lpKeyName,
LPCSTR lpDefault,
LPSTR lpReturnedString,
DWORD nSize,
LPCSTR lpFileName
输出参数 : LPSTR lpReturnedString,
返 回 值 : 字符串长度
调用函数 :
被调函数 :
修改历史 :
1.日 期 : 2013年11月18日
作 者 :
修改内容 : 新生成函数
*****************************************************************************/
DWORD WINAPI EML_GetPrivateProfileString(
LPCSTR lpAppName,
LPCSTR lpKeyName,
LPCSTR lpDefault,
LPSTR lpReturnedString,
DWORD nSize,
LPCSTR lpFileName)
{
FILE *hFile;
char szHeadApp[BUFFER_SIZE] = {0};
char szBuffer[BUFFER_SIZE] = {0};
int nResult = 0;
if (!lpAppName || !lpKeyName || !lpReturnedString || !lpFileName)
{
return nResult;
}
if (lpDefault)
{
strncpy(lpReturnedString,lpDefault,nSize);
}
else
{
*lpReturnedString=0;
}
hFile = fopen(lpFileName,"r");
if (!hFile)
{
printf("EML_GetPrivateProfileString1: lpReturnedString == %s", lpReturnedString);
return nResult;
}
sprintf(szHeadApp,"[%s]",lpAppName);
/*search key word*/
while (!feof(hFile))
{
if (fgets(szBuffer, BUFFER_SIZE, hFile))
{
if (szBuffer[strlen(szBuffer)-1] == '\n')
{
szBuffer[strlen(szBuffer)-1] = '\0';
}
if (strcmp(szBuffer,szHeadApp) == 0)
{
break;
}
}
else
{
fclose(hFile);
printf("EML_GetPrivateProfileString2: lpReturnedString == %s", lpReturnedString);
return nResult;
}
}
/*search for key*/
while (!feof(hFile))
{
if (fgets(szBuffer,BUFFER_SIZE,hFile))
{
char *szEqual = strstr(szBuffer, "=");
if (szEqual)
{
*szEqual=0;
if (strnicmp(szBuffer,lpKeyName, strlen(lpKeyName))==0)
{
szEqual++;
while (*szEqual==' ')
{
szEqual++;
}
strncpy(lpReturnedString,szEqual,nSize);
nResult = nSize;
break;
}
}
}
else
{
printf("EML_GetPrivateProfileString3: lpReturnedString == %s, szBuffer == %s", lpReturnedString, szBuffer);
fclose(hFile);
return nResult;
}
}
printf("EML_GetPrivateProfileString4: lpReturnedString == %s", lpReturnedString);
fclose(hFile);
return nResult;
}
/*****************************************************************************
函 数 名 : HotPatchWin32API
功能描述 : 修改API调用跳转实现,修改API实现功能
输入参数 : FUN_PTR pfnOld,
FUN_PTR pfnNew
输出参数 : 无
返 回 值 : BOOL bResult
调用函数 :
被调函数 :
修改历史 :
1.日 期 : 2013年11月18日
作 者 :
修改内容 : 新生成函数
*****************************************************************************/
BOOL HotPatchWin32API(FUN_PTR pfnOld, FUN_PTR pfnNew)
{
DWORD dwOldProtect = 0;
BOOL bResult = FALSE;
CHAR* pcPatchAddress = NULL;
pcPatchAddress = (char *)pfnOld - PATCH_OFFSET;
bResult = VirtualProtect(pcPatchAddress, PATCH_SIZE, PAGE_EXECUTE_READWRITE, &dwOldProtect);
if (bResult != TRUE)
{
return FALSE;
}
*(pcPatchAddress + LONGJUMP_OFFSET) = LONG_JUMP; //long jump指令
*(pcPatchAddress + SHORTJUMP_OFFSET) = SHORT_JUMP; //shot jump 指令
*(DWORD *)(pcPatchAddress + ADDRESS_OFFSET) = (char *)pfnNew - (char *)pfnOld; //4字节相对偏移
*(pcPatchAddress + SHORTJUMP_OFFSET + ADDRESS_OFFSET) = SHORTJUMP_ADDRESS; //1字节相对偏移
//恢复PAGE_EXECTE_READ
bResult = VirtualProtect(pcPatchAddress, PATCH_SIZE, dwOldProtect, &dwOldProtect);
if (bResult != TRUE)
{
return FALSE;
}
return TRUE;
}
三、主函数:main.c
#include "AnalysisIniFile.h"
int main(int argc, char * argv[])
{
BOOL iHook = FALSE;
char *szConfigFileName = "config.ini";
char szPathName[BUFFER_SIZE] = {0};
int mPortNumber = 0;
char szStr[BUFFER_SIZE] = {0};
iHook = HotPatchWin32API(GetPrivateProfileString, EML_GetPrivateProfileString);
if (iHook == FALSE)
{
printf("Error at HotPatchWin32API GetPrivateProfileString!");
return RETURN_ERR;
}
if (RETURN_ERR == GetCurrentDirectory((DWORD)sizeof(szPathName), szPathName))
{
printf("GetCurrentDirectory fail %d.", (int)GetLastError());
return RETURN_ERR;
}
snprintf(szPathName, sizeof(szPathName), "%s\\%s", szPathName, szConfigFileName);
mPortNumber = GetPrivateProfileInt("PORT", "EmlBindPort", 0, szPathName);
if (RETURN_ERR == GetPrivateProfileString("IP", "Ctrl0_bond0", NULL, szStr, (DWORD)sizeof(szStr), szPathName))
{
printf("Get String FAIL %d.", (int)GetLastError());
}
system("pause");
return RETURN_OK;
}