实现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

 

原文地址:https://www.cnblogs.com/qianqing/p/11186546.html

时间: 2024-08-07 07:06:43

实现win10下Delphi 10.3和易语言 inline hook之GetLocalTime的相关文章

Go将统治下一个10年?Go语言发展现状分析

"本文是国内Go语言大中华区首席布道师--许式伟,在QCon2015上海站上的分享.他预测Go语言10年内一定会超过C和java,并且统治这一个10年. Go语言语法及标准库变化 Go从1.0版本到现在(2015年)已经有三年多的时间,大的版本发布了五个,下面大家一起看看每个大版本分别都改了什么,当然这里不可能把所有的细节都提到,但我认为重要的会提出来. 首先是Go1.1,Go1.0于2012年4月发布,此后基本维持了每半年发布一个新版本的时间间隔.Go1.5比较例外,在Go1.5的拖累下,Go

Win10 在 CUDA 10.1 下跑 TensorFlow 2.x

深度学习最热的两个框架是 pytorch 和 tensorflow,pytorch 最新版本是 1.3,tensorflow 最新版本为 2.0,在 win10 下 pytorch 1.3 要求的 cuda 最高版本是 10.1,见下图: 而 tensorflow 2.0 使用的 cuda 版本是 10.0,见下图: 这就造成了冲突,一般是装 cuda 10.1,然后再重新编译 tensorflow 2.0 源码跑在 cuda 10.1 下,编译 tensorflow 源码的步骤还是较麻烦的,也

win10下安装Ubuntukylin+修复Ubuntu引导+双系统可选启动

为了方便以后给自己机器重装linux用,简单记录一下.如果有其他人有需要启动盘或者有其他问题可以留言. 1)安装Ubuntukylin <1>先在win10下,鼠标右键我的电脑,点击管理,打开磁盘那一栏,可以把之前不用的磁盘卷删除(会自动合并),如果你不知道那些没有名字但又占了空间的磁盘是干嘛用的,那就不要乱删:然后如果要将F或者G之类的已经写了字母的盘拿出一个来给Ubuntu的话,注意提前将里面重要东西剪切到另一个盘中做好备份,然后这个盘先不要格式化,记住这个盘的已经使用大小和这个盘总空间的

使用delphi 10.2 开发linux 上的Daemon

delphi 10.2 支持linux, 而且官方只是支持命令行编程,目地就是做linux 服务器端的开发. 既然是做linux服务器端的开发,那么普通的命令行运行程序,然后等待开一个黑窗口的方式就 太low了(目前就有个别语言大咖,经常在Windows 上开个黑窗口,看起来非常恶心),那么如果 避免这个尴尬的问题? 其实Linux 下也有类似windows 服务的功能,Linux Daemon 就是其中的一种方式,命令行运行后 直接返回,同时在后台建立一个同样的进程.接受客户端的访问.常见的一

delphi 10 seattle 安卓服务开发(一)

从delphi 开始支持安卓的开发开始, 安卓service 开发一直都是delphier 绕不过去的坎, 以前也有开发service  的方法,但是都是手工处理启动文件,而且要修改很多东西,基本上成功 的概率很低. delphi 10 seattle(这个名字很特殊,与win10 一样,直接跳过了9) 终于官方支持安卓service 开发了, 不知道现在现在开发安卓service 是不是很简单?那么就让我们一探究竟. 首先,我们开启已经扁平的不能再扁平delphi 10, 选择建立一个其他项目

Vim配置:在win10下编译运行C/C++

Vim配置:在win10下编译运行C/C++ 为什么用Vim nvim对windows实在是不是很友好,所以打算弃坑.本来想直接用spacevim的,本来以前安装好了,无奈手贱,给删了,现在在配置后发现老是有问题,所以放弃spacevim,在过个半年一年之后再来看看. 所以,开始重新调配vim. 安装 官网下载 PC: MS-DOS and MS-Windows下的 For modern MS-Windows systems (starting with XP) you can simply u

Win10下安装Python3及Python2、数据类型、格式化输出、运算符

Win10下安装Python3及Python2 下载的官网地址: https://www.python.org/downloads/windows/ 安装Python3: 安装完成之后,在开始处输入 cmd ,测试Python是否安装成功. 输入: python -V ----> pip -v ----> pip 安装Python2: 安装完成之后,打开之前打开的命令提示符页面,测试Python是否安装成功. 输入: python -V ----> pip -v Python3.x与Py

win10下VSCode+CMake+Clang+GCC环境搭建

win10下VSCode+CMake+Clang+GCC环境搭建 win10下VSCode+CMake+Clang+GCC环境搭建 安装软件 VSCode插件安装 新建文件夹, 开始撸代码 main.cpp CMakeList.txt 配置 c_cpp_properties.json 配置调试文件 launch.json 配置CMake 编译和调试 打算用C/C++把基本的数据结构与算法实现一遍, 为考研做准备, 因为只是想实现算法和数据结构, 就不太想用VisualStudio, 感觉VSCo

win10下通过Anaconda安装TensorFlow-GPU1.3版本,并配置pycharm运行Mnist手写识别程序

折腾了一天半终于装好了win10下的TensorFlow-GPU版,在这里做个记录. 准备安装包: visual studio 2015: Anaconda3-4.2.0-Windows-x86_64: pycharm-community: CUDA:cuda_8.0.61_win10:下载时选择 exe(local) CUDA补丁:cuda_8.0.61.2_windows: cuDNN:cudnn-8.0-windows10-x64-v6.0;如果你安装的TensorFlow版本和我一样1.