实现win10下Delphi 10.3和易语言 inline hook之GetLocalTime

Posted qianqing

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了实现win10下Delphi 10.3和易语言 inline hook之GetLocalTime相关的知识,希望对你有一定的参考价值。

 1 library Project1;
 2 
 3  Important note about DLL memory management: ShareMem must be the
 4   first unit in your library‘s USES clause AND your project‘s (select
 5   Project-View Source) USES clause if your DLL exports any procedures or
 6   functions that pass strings as parameters or function results. This
 7   applies to all strings passed to and from your DLL--even those that
 8   are nested in records and classes. ShareMem is the interface unit to
 9   the BORLNDMM.DLL shared memory manager, which must be deployed along
10   with your DLL. To avoid using BORLNDMM.DLL, pass string information
11   using PChar or ShortString parameters. 
12 
13 uses
14   System.SysUtils,
15   System.Classes,
16   Winapi.Windows;  //加载自动声明api的库
17 
18 $R *.res
19 
20 var
21   read: array[1..5] of Byte;  //保存api头部的前5个字节
22   apiaddr: Integer;  //保存api地址
23   rd: NativeUInt;  //wreiteprocessmemory或者readprocessmemory的最后一个参数,表示实际读取或者写入的字节数
24   jmps: Integer;  //jmp的10进制,也就是16进制的E9
25   tiaoshi, tiaoshi1: Integer;  //调试输出代码用,可取消
26   function MyMoveMemo(old:Integer;New:Pointer;size:Integer):integer;stdcall;external kernel32.dll  name RtlMoveMemory;  //这里需要用MoveMemory将我们自定义的时间覆盖用正常api获取的时间,第一个参数是旧的内容,第二个参数是新的内容,第三个参数是大小,由于我们定义的变量是自定义数据类型_systemtime
                                                                           //无法使用MoveMemory,这个函数要求第一和第二个参数都为整型,所以我们必须自定义这个api函数,使其第二个参数为pointer类型才能调用
27 function lens(x, y: Integer): Integer; //计算Jmp的距离,也就是从api地址跳到我们新函数的距离 28 begin 29 Result := x - y - 5; 30 end; 31 32 procedure HookTime( lpSystemTime:Integer); stdcall; //这里是我们定义的新函数,他没有返回值,返回值就在他的参数当中 33 var 34 i:Integer; //这里是循环恢复Hook的循环次数 35 Ntime: _SYSTEMTIME; //这里是我们定义的变量,用来保存我们自己设定的时间 36 a:Integer; //这里是看是否覆盖内容 37 begin 38 OutputDebugString(PWideChar(IntToStr(lpSystemTime))); //先调试输出一下看他的内容 39 for i := 1 to 5 do 40 begin 41 WriteProcessMemory(GetCurrentProcess, Pointer(apiaddr + i - 1), Pointer(@read[i]), 1, rd); //循环恢复头5个字节,因为这个函数是要先调用他的参数才有内容 42 OutputDebugString(PWideChar(IntToStr(read[i]))); 43 end; 44 // local := IntToStr(Integer(@lpSystemTime)); //lpsystemtime=参数A,加@的B地址保存着A地址, 45 // local := IntToStr(Integer(@time)); //lpsystemtime=参数A,加@的B地址保存着A地址, 46 Ntime.wYear := 2018; //定义时间,占2个字节,总共8个成员,所以是16,一般用sizeof 或者localsize 这个api函数 47 Ntime.wMonth := 1; 48 Ntime.wDayOfWeek := 3; 49 Ntime.wDay := 2; 50 Ntime.wHour := 4; 51 Ntime.wMinute := 5; 52 Ntime.wSecond := 6; 53 Ntime.wMilliseconds := 7; 54 a:=MyMoveMemo(lpSystemTime,@Ntime,16) ; //这里是将我们定义的时间覆盖掉他的参数里面的时间,大小是16个字节,每个成员占2个字节,共8个成员,MoveMemory这个函数的参数必须为整型,但是我们这个变量的值是一个自定义数据类型,所以我们需要取这个变量的地址转成Pointer类型才能覆盖 55 OutputDebugString(PWideChar(IntToStr(a))); 56 end; 57                  //这里解释一下lpsystemTime这个参数,这个参数里面包含着16个字节的时间,假设地址为A,我们用@取的地址B,B地址保存着A这个地址,A这个地址才保存着时间,但是我们用Lpsystemtime.wYear写的时间却覆盖的是B地址保存的内容,也就是B的内容不再保存着A这个地址,而是保存我们定义的时间,我们必须要修改A地址保存的时间才有效。 58 59 60 61 procedure hooked; 62 63 64 begin 65 apiaddr := Integer(GetProcAddress(LoadLibrary(kernel32.dll), GetLocalTime)); 66 ReadProcessMemory(GetCurrentProcess, Pointer(apiaddr), Pointer(@read), 5, rd); 67 jmps := 233; 68 WriteProcessMemory(GetCurrentProcess, Pointer(apiaddr), Pointer(@jmps), 1, rd); 69 tiaoshi := Integer(@HookTime); 70 tiaoshi1 := lens(Integer(@HookTime), apiaddr); 71 WriteProcessMemory(GetCurrentProcess, Pointer(apiaddr+1), Pointer(@tiaoshi1), 4, rd); 72 end; 73 74 begin 75 76 hooked; //这里相当于DllMain 如果将函数或者过程放到这里,将会在dll运行的时候调用 77 78 end.
ASM 硬编码修改时间:易语言这里需要修改KernelBase.dll里面这个GetLocalTime,

13 14 772FD0A0 > 60 pushad 15 772FD0A1 9C pushfd 16 772FD0A2 66:36:C700 E207 mov word ptr ss:[eax], 0x7E2 //年 7E2=2018,这里是16进制应该转10进制 17 772FD0A8 66:36:C740 02 0>mov word ptr ss:[eax+0x2], 0x7 // 18 772FD0AF 66:36:C740 04 0>mov word ptr ss:[eax+0x4], 0x4 //星期几 19 772FD0B6 66:36:C740 06 0>mov word ptr ss:[eax+0x6], 0xB // 20 772FD0BD 66:36:C740 08 1>mov word ptr ss:[eax+0x8], 0x11 // 时 这里的11是16进制,应该转10进制 21 772FD0C4 66:36:C740 0A 2>mov word ptr ss:[eax+0xA], 0x21 // 22 772FD0CB 66:36:C740 0C 3>mov word ptr ss:[eax+0xC], 0x39 // 23 772FD0D2 66:36:C740 0E 4>mov word ptr ss:[eax+0xE], 0x48 // 24 772FD0D9 9D popfd 25 772FD0DA 61 popad 26 772FD0DB C3 retn //这里的retn只针对易语言,因为调用这个api函数是push了一个参数,最终应该是retn 4 或者mov,ebp,esp pop ebp 或者是leave再retn 27 28 60 9C 66 36 C7 00 E2 07 66 36 C7 40 02 07 00 66 36 C7 40 04 04 00 66 36 C7 40 06 0B 00 66 36 C7 40 08 11 00 66 36 C7 40 0A 21 00 66 36 C7 40 0C 39 00 66 36 C7 40 0E 48 00 9D 61 C3 //这里是保存的16进制的 29 30 772FD0A0 > 60 pushad 31 772FD0A1 9C pushfd 32 772FD0A2 36:C700 E2070700 mov dword ptr ss:[eax], 0x707E2 33 772FD0A9 36:C740 04 04000B00 mov dword ptr ss:[eax+0x4], 0xB0004 34 772FD0B1 36:C740 08 11002100 mov dword ptr ss:[eax+0x8], 0x210011 35 772FD0B9 36:C740 0C 39004800 mov dword ptr ss:[eax+0xC], 0x480039 36 772FD0C1 9D popfd 37 772FD0C2 61 popad 38 772FD0C3 C3 retn 39 40 41 42 60 9C 36 C7 00 E2 07 07 00 36 C7 40 04 04 00 0B 00 36 C7 40 08 11 00 21 00 36 C7 40 0C 39 00 48 00 9D 61 C3 //共36 Byte 43 44 45 (60,9C,36,C7,00 ,E2 ,07 ,07 ,00 ,36 ,C7 ,40 ,04 ,04 ,00 ,0B ,00 ,36, C7 ,40 ,08 ,11 ,00 ,21 ,00 ,36 ,C7 ,40 ,0C ,39 ,00 ,48 ,00 ,9D ,61 ,C3);
易语言的APIHook代码,需要用精易模块

.版本 2 .程序集 程序集1 .程序集变量 H00K_GetLocalTime, 类_APIHOOK .子程序 _启动子程序, 整数型, 公开, 请在本子程序中放置动态链接库初始化代码 H00K_GetLocalTime.安装 (“kernel32.dll”, “GetLocalTime”, &现行时间_新) _临时子程序 () 在初始化代码执行完毕后调用测试代码 返回 (0) 返回值被忽略。 .子程序 现行时间_新 .参数 时间, 整数型 //这里因为易语言Hook以后只能调用整型,没办法用自定义类型,所以让他用整型 .局部变量 新时间, 精易_时间 //声明一个局部变量,类型就是自定义类型,后面我们再覆盖 H00K_GetLocalTime.暂停 (“kernel32.dll”, “GetLocalTime”) 新时间.年 = 2010 新时间.月 = 9 新时间.日 = 10 新时间.时 = 11 新时间.分 = 12 新时间.秒 = 13 MoveMemory (时间, 新时间, 16) movmemory函数(源内存,用于替换源内存的目标内存,大小)作用:将一段内存块覆盖到原有的内存块当中,由于GetlocalTime的参数,就是他的返回值,里面的内容我们用自定义的内容覆盖即可, 至于大小为什么是16,由于精易_时间这个自定义数据类型当中共有8个成员,短整数=Smallint,每个占2个字节,共8*2=16个字节大小 H00K_GetLocalTime.继续 (“kernel32.dll”, “GetLocalTime”) .子程序 _临时子程序 本名称子程序用作测试程序用,仅在开发及调试环境中有效,编译发布程序前将被系统自动清空,请将所有用作测试的临时代码放在本子程序中。 ***注意不要修改本子程序的名称、参数及返回值类型。
//

.版本 2


.DLL命令 MoveMemory, , , "RtlMoveMemory", , 重叠复制,将目标内存替换掉源内存    //这里是DLL命令
.参数 Destination, 整数型
.参数 Source, 精易_时间
.参数 cbCopy, 整数型

 

.数据类型 精易_时间, 公开, , SYSTEMTIME        //这里是自定义数据类型
.成员 年, 短整数型, , "", wYear   
.成员 月, 短整数型, , "", wMonth  
  .成员 星期, 短整数型, , "",    
.成员 日, 短整数型, , "", wDay   
.成员 时, 短整数型, , "", wHour   
.成员 分, 短整数型, , "", wMinute  
  .成员 秒, 短整数型, , "", wSecond   
.成员 毫, 短整数型, , "", wMilliseconds   //短整数型=smallint 有符号16位,占2个字节,总共8个成员,所以8*2=16

 

 

以上是关于实现win10下Delphi 10.3和易语言 inline hook之GetLocalTime的主要内容,如果未能解决你的问题,请参考以下文章

Delphi 10.3 上的“名称为“ecSwapCppHdrFiles”的组件已经存在”

Delphi 10.3:找不到所需的包

转:Delphi10.3 中通过JNI调用 Java 函数

Delphi 10.3最新消息

Delphi中ARC内存管理的方向

Delphi 10.3.1来了