How To Remove Watermark By Programing
--------------------------------------------------------------------------------
作者: 发布时间:2009-05-10 12:59:02 浏览次数:45
Some friends asked me how to remove the watermark by programming, now, I have post a demo to google code. You can found the source code at
http://code.google.com/p/removewatermark/
Main steps:
Load the user32.dll.mui into memory by API LoadLibraryEx().
Find the string table by FindResourceEx(), and load it by LoadResource(), LockResource().
Look up the watermark string in string table, we can get the string virtual address and length, then calculate the string offset base the module address, and we get the file offset.
Map the file to memory, just simple zero the watermark string.
In order to make the procedure simple, so use the simplest method.
Finally, re-check sum the file.
OK, all done.
Code snippet:
// Load string from resource with special langID
//
BOOL LoadStringExx(
HINSTANCE hInst, // Hinstance of lib
WORD wLangID, // Language ID of resource
PRES_STRING_INFO pInfo // Pointer to the string info
)
{
HRSRC hFindRes; // Handle of the resources has been found
HGLOBAL hLoadRes; // Handle of the resources has been loaded
LPVOID pRes; // Pointer to the resources
UINT nBlockID; // String block ID
pInfo->dwFileOffset = 0; // String offset in the file
pInfo->dwBytes = 0; // String length, in bytes
pInfo->pszText = NULL;
nBlockID = pInfo->uStringID / 16 + 1;
__try
{
// find the string block
hFindRes = FindResourceEx(hInst, RT_STRING, MAKEINTRESOURCE(nBlockID), wLangID);
if(!hFindRes )
{
__leave;
}
hLoadRes = LoadResource(hInst, hFindRes);
if(!hLoadRes )
{
__leave;
}
pRes = LockResource(hLoadRes);
if(!pRes )
{
__leave;
}
WCHAR* pParse = (WCHAR *)pRes; // Pointer to the String block
UINT nIndex = pInfo->uStringID % 16; // Calculate the string index
int nLen;
UINT i;
// 16 strings per block
for( i = 0; i < (nIndex & 15); i++ )
{
pParse += 1 + (int)*pParse;
}
// OK, we get it
nLen = (UINT)*pParse; // The length of the target string.
pParse += 1; // Pointer to the target string
// Main point, calculate the string offset
pInfo->dwFileOffset = (DWORD) ( (DWORD_PTR)pParse - (DWORD_PTR)hInst ) + 1;
pInfo->dwBytes = nLen * sizeof(WCHAR);
// allocate memory
pInfo->pszText = (LPWSTR)MALLOC((nLen + 1) * sizeof(WCHAR));
if (!pInfo->pszText)
__leave;
// copy string for return
CopyMemory((LPVOID)pInfo->pszText, (LPVOID)pParse, pInfo->dwBytes);
*(PWCHAR)((DWORD_PTR)pInfo->pszText + pInfo->dwBytes) = 0;
}
__finally
{
// Clean up, free memory
if (pRes)
UnlockResource(pRes);
if (hFindRes)
FreeResource(hFindRes);
}
// if pointer is null, we return a NULL string
if (!pInfo->pszText)
{
pInfo->pszText = (LPWSTR)MALLOC(sizeof(WCHAR));
pInfo->pszText[0] = 0;
}
return TRUE;
} // LoadStringExx()