L
lovezyp
Unregistered / Unconfirmed
GUEST, unregistred user!
看到已经有不少软件做到了,运行的时候把系统托盘的时钟给替换了,显示自己的时间,但是不知道怎么做,听说原理是注入,有个软件chken tray clock给出了一个cpp源码:#include "Main.h"#include "Common.h"#ifdef _WIN64 #include "../Res/DLLx64_i.hpp"#else #include "../Res/DLL_i.hpp"#endif#include "Language.h"#include "Language_i.hpp"inline KEN_NO_INLINE void KEN_FASTCALL MsgErrorBox(LPCTSTR pErrText){ MessageBox(NULL,pErrText,TGETLS(s_LoadErrorTitle),MB_OK|MB_ICONSTOP|MB_SYSTEMMODAL);}inline void KEN_FASTCALL GoHome(){ ShellExecuteA(NULL,"open","http://www.CHKen.com",NULL,NULL,SW_SHOWMAXIMIZED);}#define MIN_PROCESSinline void KEN_FASTCALL MinCloseHandle(HANDLE hObject){ #ifndef MIN_PROCESS CloseHandle(hObject); #endif}KEN_NO_RETURN KEN_NO_INLINE void KEN_FASTCALL MyExitProcess(){ExitProcess(0);}extern "C" FARPROC (WINAPI * MyGetProcAddress)(HMODULE,LPCSTR);#include "xImport.hpp"void KenMain(){ MyGetProcAddress=&GetProcAddress; InitXImport(); struct{ HANDLE m_hMutex; }m_RunOnce; m_RunOnce.m_hMutex=CreateMutexA(NULL,TRUE,"Ken.TrayClockWClass"); if(GetLastError()==ERROR_ALREADY_EXISTS)MyExitProcess(); #define hCurrentProcess ( (HANDLE)(-1) ) //HANDLE hCurrentProcess=KenGetCurrentProcess(); #ifndef _WIN64 BOOL bIsWow64; if(&IsWow64Process && IsWow64Process(hCurrentProcess,&bIsWow64))if(bIsWow64){ MsgErrorBox(TGETLS(s_Notx64System)); GoHome(); MyExitProcess(); } if(&CreateRemoteThread==NULL){ MsgErrorBox(TGETLS(s_CannotInWin9x)); MyExitProcess(); } #endif static CHAR pTrayWndsClassName[][ RTL_NUMBER_OF("TrayClockWClass") ]={ ("Shell_TrayWnd"),("TrayNotifyWnd"),("TrayClockWClass") }; LPCTSTR pErrText=TGETLS(s_CannotFindTrayClockWnd); CKWnd hTrayClockWnd=NULL; for( LPCSTR pClassName=pTrayWndsClassName[0]; pClassName<pTrayWndsClassName[RTL_NUMBER_OF(pTrayWndsClassName)]; pClassName+=RTL_NUMBER_OF(pTrayWndsClassName[0]) ) if(! (hTrayClockWnd=FindWindowExA(hTrayClockWnd,NULL,pClassName,NULL)) )goto pErrExit; { pErrText=TGETLS(s_CannotOpenSysThread); DWORD dwProcessID=hTrayClockWnd.GetWindowProcessID(); HANDLE hProcess=OpenProcess(PROCESS_CREATE_THREAD|PROCESS_VM_WRITE|PROCESS_VM_OPERATION|PROCESS_DUP_HANDLE,FALSE,dwProcessID); if(hProcess){ pErrText=TGETLS(s_CannotStartRemoteThread);#ifdef DLL_PACK #define ImageHeadSize ( DWORD(sizeof(TRemoteDllParam)+0x10-1) & ~DWORD(0x10-1) ) #define DllImageSize (DLL_SizeOfImage-DLL_FirstVirtualAddress) #define DllImageEnd (ImageHeadSize+DllImageSize) #define TrueSizeOfImage (ImageHeadSize+DllImageSize+MAX_PATH*sizeof(TCHAR)) #define FirstRawDataVirtualAddress (ImageHeadSize+(DLL_FirstRawDataVirtualAddress-DLL_FirstVirtualAddress)) #define DllAddressOfEntryPoint (DLL_AddressOfEntryPoint+ImageHeadSize-DLL_FirstVirtualAddress)#else #define DllImageSize (DLL_SizeOfImage) #define DllImageEnd (DLL_SizeOfImage) #define TrueSizeOfImage (DLL_SizeOfImage+MAX_PATH*sizeof(TCHAR)) #define FirstRawDataVirtualAddress (DLL_FirstRawDataVirtualAddress) #define DllAddressOfEntryPoint (DLL_AddressOfEntryPoint) ASSERT(DLL_e_lfanew+FIELD_OFFSET(IMAGE_NT_HEADERS,OptionalHeader.ImageBase)>sizeof(TRemoteDllParam));#endif ASSERT(DLL_IsPE_DataOnly); ASSERT(sizeof(DLL)==DLL_RawDataSize); ASSERT(DLL_FirstRawDataVirtualAddress+DLL_RawDataSize<=DLL_SizeOfImage); //LPBYTE LocalImage=(LPBYTE)malloc(TrueSizeOfImage); ZeroMemory(LocalImage,TrueSizeOfImage); //ZeroMemory(LocalImage,TrueSizeOfImage); BYTE LocalImage[TrueSizeOfImage];#ifndef DLL_PACK if( (TrueSizeOfImage % sizeof(DWORD)) == 0 )__stosd(LPDWORD(LocalImage),0,TrueSizeOfImage/sizeof(DWORD)); else __stosb(LocalImage,0,TrueSizeOfImage);#endif //memcpy(LocalImage+FirstRawDataVirtualAddress,DLL,DLL_RawDataSize); if( (DLL_RawDataSize % sizeof(DWORD)) == 0 )__movsd(LPDWORD(LocalImage+FirstRawDataVirtualAddress),LPDWORD(DLL),DLL_RawDataSize/sizeof(DWORD)); else __movsb(LocalImage+FirstRawDataVirtualAddress,DLL,DLL_RawDataSize);#ifndef DLL_PACK PIMAGE_DOS_HEADER(LocalImage)->e_lfanew=DLL_e_lfanew; PIMAGE_NT_HEADERS pNtHeaders=PIMAGE_NT_HEADERS(LocalImage+DLL_e_lfanew); pNtHeaders->OptionalHeader.ImageBase=DLL_ImageBase; pNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress=DLL_DataDir_Import_VirtualAddress; pNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress=DLL_DataDir_BaseReloc_VirtualAddress;#else #ifdef _WIN64 ASSERT(*PDWORD(LocalImage+DllAddressOfEntryPoint)==0x57565251); //测试是否压缩了 #else ASSERT(*PDWORD(LocalImage+DllAddressOfEntryPoint)==0x000015E8); //测试是否压缩了 #endif#endif #define RemoteParam (*(TRemoteDllParam*)LocalImage) RemoteParam.hMainWnd=hTrayClockWnd; ASSERT(FIELD_OFFSET(TRemoteDllParam,pLoadLibraryA)==sizeof(LPVOID)); ASSERT(!IsApiJmp(&LoadLibraryA)); ASSERT(!IsApiJmp(MyGetProcAddress)); RemoteParam.pLoadLibraryA=&LoadLibraryA; RemoteParam.pGetProcAddress=MyGetProcAddress; GetModuleFileName(NULL,LPTSTR(LocalImage+DllImageEnd),MAX_PATH); DuplicateHandle(hCurrentProcess,m_RunOnce.m_hMutex, hProcess,&RemoteParam.m_hRunOneMutex, 0,FALSE,DUPLICATE_SAME_ACCESS|DUPLICATE_CLOSE_SOURCE); PVOID pImage=VirtualAllocEx(hProcess,NULL,TrueSizeOfImage,MEM_RESERVE|MEM_COMMIT,PAGE_EXECUTE_READWRITE); if(pImage){ RemoteParam.pMainExeFile=LPTSTR(LPBYTE(pImage)+DllImageEnd); if(WriteProcessMemory(hProcess,pImage,LocalImage,TrueSizeOfImage,NULL)){ LPVOID AddressOfEntryPoint=(LPBYTE)pImage+DllAddressOfEntryPoint; HANDLE hThread=CreateRemoteThread(hProcess,NULL,0,(LPTHREAD_START_ROUTINE)AddressOfEntryPoint,pImage,0,NULL); if(hThread){ pErrText=NULL; //WaitForSingleObject(hThread,INFINITE); MinCloseHandle(hThread); } } //VirtualFreeEx(hProcess,pImage,NULL,MEM_RELEASE); } if(pErrText){ DuplicateHandle(hProcess,RemoteParam.m_hRunOneMutex, hCurrentProcess,&RemoteParam.m_hRunOneMutex, 0,FALSE,DUPLICATE_SAME_ACCESS|DUPLICATE_CLOSE_SOURCE); CloseHandle(RemoteParam.m_hRunOneMutex); } MinCloseHandle(hProcess); //free(LocalImage); } }pErrExit: if(pErrText)MsgErrorBox(pErrText); MyExitProcess();}#pragma comment(linker, "/ENTRY:main")#ifndef _DEBUG #pragma comment(linker, "/merge:.rdata=.text") #pragma comment(linker, "/merge:.data=.text") #pragma comment(linker, "/SECTION:.text,ERW")#endifdelphi下怎么实现呢?任何方法都可以 他替换后单击时钟区域会显示自己的菜单