搜索API函数地址

实验 3    PE 病毒分析与清除(二)

3.1 实验名称

PE 病毒分析与清除

3.2 实验目的

1)  了解 PE 病毒的基本原理

2)  熟悉 PE 病毒中的部分关键技术

3)  学会清除 PE 病毒

3.3 实验步骤及内容

第一阶段:

 熟悉 Masm32

1)    安装 masm32v11

2)    熟悉 masm32 的基本环境

3)    写一个最简单的 HelloWorld 程序,并编译成功

4)    对得到的可执行文件进行反汇编, 比较其反汇编代码和最初的汇编代码有 哪些异同?

5)    查看并理解 masm32\bin 下各个批处理程序,了解它们的大致功能

第二阶段:

 熟悉病毒重定位的基本思路和方法

  在 HelloWorld.exe 中添加一段代码, 该段代码满足以下几个条件:

该段代码弹出一个对话框(标题: 武大信安病毒重定位,内容: 姓 名+学号后四位)

该段代码同时包括代码和字符串数据。

该段代码可以插入到.text  节的任意指令之间,而不需要修改该段代 码中的任何字节。

第三阶段:

 搜索 API 函数地址

  用 ollydbg  打开 HelloWorld.exe ,获取 kernel32.dll  模块基地址,定位到

kernel32.dll 模块。

  从内存中的 kernel32.dll 模块获取函数 LoadLibraryA 和 GetProcAddress 的函

数地址,并实际检验获得的地址是否正确

第四阶段: PE 病毒感染分析与清除

 编译教材中的感染例子程序-bookexample-old.rar

使用该感染例子对 HelloWorld.exe 进行感染。思考以下问题:

  该病毒在感染文件时具体做了哪些操作?

  该病毒如何返回 HOST?

找出该病毒程序存在的一些问题,并解决这些问题。

编译教材中的感染例子程序-bookexample-new.rar

使用该感染例子对计算器 calc.exe 进行感染。

手工恢复被感染的 calc.exe  (功能恢复)。

课后习题思考:

 对 Win10 下的在 32 位及 64 位程序来说, 如何通过 PEB 获取 kernel32 基地址? 32 位和 64 程序有何差异?

 尝试编写一个程序,可用来搜索指定目录下的所有 exe 文件,用 MessageBox 显示每 一个被搜索到的 exe 文件名。

 编写课本中病毒感染程序的病毒清除程序,其可以用来恢复被感染的任何文件

 课程提供的病毒感染例子程序在 64 位系统中无法正常感染, 请定位其原因, 并给出 解决方案。

3.4 实验关键过程、数据及其分析

搜索 API 函数地址

NT内核系统中FS寄存器指向TEB结构,TEB+0x30处指向PEB结构,PEB+0x0C处指向PEB_LDR_DATA结构。

PEB_LDR_DATA+0x1c处是一个叫InInitialzationOrderModuleList的成员,指向LDR_MODULE双向链表结构,存放一些动态链接库地址:第一个指向ntdl.dll,第二个就是kernel32.dll。

使用Ollydbg打开helloworld.exe。更改数据窗口的显示模式->长型->地址,这样数据窗口数值就能和地址相对应。

找到FS地址,对其30的偏移量,跳转转到 7FFDF030,并在数据窗口中跟随PEB中的数据。

然后再加一个0C的偏移量,再进行数据窗口跟随找到PEB_LDR_DATA结构。

接下来再有一个1C的偏移量,再次进行数据窗口跟随,找到了双向链表的结构。

结构中,第一个值是指向下一个指针,第二个值是指向上一个指针。可以看到双向链表中第一个值是ntdll模块的地址0x7C920000。根据双向链表的结构,跟随第一个指针,找到可链表的下一个节点。

这样可以找到kernel32的基地址0x7C800000。验证一下,第二个指针也确实指向上一个也就是ntdll的地址。再验证一下,选择查看内存,可以看到两个库函数的基地址均正确。

找到基地址后,我们还需要找到函数地址。

首先需要找到kernel32模块的导出表结构。导出表结构如下图所示,AddressOfNames在偏移0x20处。

   通过导出表获取函数地址分为以下三步:1.AddressOfNames字段里存放着函数名的地址,遍历匹配函数名,找到后返回一个该函数名地址的索引index_name;2.再查看AddressOfNameOrdinals字段中index_name处存放的值,设为index_i;3.最后查找AddressOfFunctions字段中index_i处存放的地址,这就是我们要找的函数地址。

首先,找到kernel32模块的基地址并双击进入,找到导出表的地址偏移为0x262C(基地址是0x7C80000)。

跳转到0x7C80262C,再找到偏移为0x20的地方,就是AddressOfNames的地址。

接下来继续跳转到AddressOfNames处,记得要加上整体的偏移0x7C80000。

可以看到函数名所在的RVA地址是0x00004BA5,跳转过去到达ExportNames可以看到所有函数名称。

接下来到将第2步,我们不使用比较查找索引的方式,而是直接使用命令行的查找命令“?LoadLibraryA”以及“?GetProcAddress”查找函数地址。
 

在反汇编窗口进行跳转,可以看到如下图两个函数的具体内容。

之所以要找这两个函数的地址,是因为LoadLibraryA函数可以加载任意的动态链接库,而GetProcAddress可以找到函数的地址,通过这两个函数,我们就可以摘到任意的函数地址。

  

  • 8
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
LINUX C函数API 1.字符测试篇 15 1.1 15 isalnum(测试字符是否为英文或数字) 15 1.2 15 isalpha (测试字符是否为英文字母) 15 1.3 16 isascii(测试字符是否为ASCII 码字符) 16 1.4 17 iscntrl(测试字符是否为ASCII 码的控制字符) 17 1.5 17 isdigit(测试字符是否为阿拉伯数字) 17 1.6 17 isgraphis(测试字符是否为可打印字符) 17 1.7 18 islower(测试字符是否为小写字母) 18 1.8 18 isprint(测试字符是(否为可打印字符) 18 1.9 19 isspace(测试字符是否为空格字符) 19 1.10 20 ispunct(测试字符是否为标点符号或特殊符号) 20 1.11 20 isupper(测试字符是否为大写英文字母) 20 1.12 21 isxdigit(测试字符是否为16进制数字) 21 2.字符串转换篇 21 2.1 21 atof(将字符串转换成浮点型数) 21 2.2 22 atoi(将字符串转换成整型数) 22 2.3 22 atol(将字符串转换成长整型数) 22 2.4 23 gcvt(将浮点型数转换为字符串,取四舍五入) 23 2.5 24 strtod(将字符串转换成浮点数) 24 2.6 24 strtol(将字符串转换成长整型数) 24 2.7 25 strtoul(将字符串转换成无符号长整型数) 25 2.8 25 toascii(将整型数转换成合法的ASCII 码字符) 25 2.9 26 tolower(将大写字母转换成小写字母) 26 2.10 26 toupper(将小写字母转换成大写字母) 26 3.内存控制篇 27 3.1 27 calloc(配置内存空间) 27 3.2 28 free(释放原先配置的内存) 28 3.3 28 getpagesize(取得内存分页大小) 28 3.4 28 malloc(配置内存空间) 28 3.5 28 mmap(建立内存映射) 28 3.6 30 munmap(解除内存映射) 30 4.日期时间篇 31 4.1 31 asctime(将时间和日期以字符串格式表示) 31 4.2 31 ctime(将时间和日期以字符串格式表示) 31 4.3 32 gettimeofday(取得目前的时间) 32 4.4 33 gmtime(取得目前时间和日期) 33 4.5 34 localtime(取得当地目前时间和日期) 34 4.6 34 mktime(将时间结构数据转换成经过的秒数) 34 4.7 35 settimeofday(设置目前时间) 35 4.8 35 time(取得目前的时间) 35 5.内存及字符串操作篇 36 5.1 36 bcmp(比较内存内容) 36 5.2 36 bcopy(拷贝内存内容) 36 5.3 37 bzero(将一段内存内容全清为零) 37 5.4 37 index(查找字符串中第一个出现的指定字符) 37 5.5. 37 memccpy(拷贝内存内容) 37 5.6 38 memchr(在某一内存范围中查找一特定字符) 38 5.7 38 memcmp(比较内存内容) 38 5.8 39 memcpy(拷贝内存内容) 39 5.9 40 memmove(拷贝内存内容) 40 5.10 40 memset(将一段内存空间填入某值) 40 5.11 40 rindex(查找字符串中最后一个出现的指定字符) 40 5.12 41 strcasecmp(忽略大小写比较字符串) 41 5.13 41 strcat(连接两字符串) 41 5.14 42 strchr(查找字符串中第一个出现的指定字符) 42 5.15 42 strcmp(比较字符串) 42 5.16 43 strcoll(采用目前区域的字符排列次序来比较字符串) 43 5.17 43 strcpy(拷贝字符串) 43 5.18 44 strcspn(返回字符串中连续不含指定字符串内容的字符数) 44 5.19 44 strdup(复制字符串) 44 5.20 45 strlen(返回字符串长度) 45 5.21 45 strncasecmp(忽略大小写比较字符串) 45 5.22 46 strncat(连接两字符串) 46 5.23 46 strncpy(拷贝字符串) 46 5.24 47 strpbrk(查找字符串中第一个出现的指定字符) 47 5.25 47 strrchr(查找字符串中最后出现的指定字符) 47 5.26 47 strspn(返回字符串中连续不含指定字符串内容的字符数) 47 5.27 48 strstr(在一字符串中查找指定的字符串) 48 5.28 48 strtok(分割字符串) 48 6. 常用数学函数篇 49 6.1 49 abs(计算整型数的绝对值) 49 6.2 49 acos(取反余弦函数数值) 49 6.3 50 asin(取反正弦函数值) 50 6.4 50 atan(取反正切函数值) 50 6.5 51 atan2(取得反正切函数值) 51 6.6 51 ceil(取不小于参数的最小整型数) 51 6.7 52 cos(取余玄函数值) 52 6.8 52 cosh(取双曲线余玄函数值) 52 6.9 53 exp(计算指数) 53 6.10 53 frexp(将浮点型数分为底数与指数) 53 6.11 54 ldexp(计算2的次方值) 54 6.12 54 log(计算以e 为底的对数值) 54 6.13 55 log10(计算以10 为底的对数值) 55 6.14 55 pow(计算次方值) 55 6.15 56 sin(取正玄函数值) 56 6.16 56 sinh(取双曲线正玄函数值) 56 6.17 56 sqrt(计算平方根值) 56 6.18 57 tan(取正切函数值) 57 6.19 57 tanh(取双曲线正切函数值) 57 7.用户组篇 58 7.1 58 endgrent(关闭组文件) 58 7.2 58 endpwent(关闭密码文件) 58 7.3 58 endutent(关闭utmp 文件) 58 7.4 59 fgetgrent(从指定的文件来读取组格式) 59 7.5 60 fgetpwent(从指定的文件来读取密码格式) 60 7.6 61 getegid(取得有效的组识别码) 61 7.7 61 geteuid(取得有效的用户识别码) 61 7.8 62 getgid(取得真实的组识别码) 62 7.9 62 getgrent(从组文件中取得账号的数据) 62 7.10 63 getgrgid(从组文件中取得指定gid 的数据) 63 7.11 64 getgrnam(从组文件中取得指定组的数据) 64 7.12 64 getgroups(取得组代码) 64 7.13 65 getpw(取得指定用户的密码文件数据) 65 7.14 66 getpwent(从密码文件中取得账号的数据) 66 7.15 67 getpwnam(从密码文件中取得指定账号的数据) 67 7.16 68 getpwuid(从密码文件中取得指定uid 的数据) 68 7.17 68 getuid(取得真实的用户识别码) 68 7.18 69 getutent(从utmp 文件中取得账号登录数据) 69 7.19 70 getutid(从utmp 文件中查找特定的记录) 70 7.20 71 getutline(从utmp 文件中查找特定的记录) 71 7.21 71 initgroups(初始化组清单) 71 7.22 71 pututline(将utmp 记录写入文件) 71 7.23 72 seteuid(设置有效的用户识别码) 72 7.24 72 setfsgid(设置文件系统的组识别码) 72 7.25 73 setfsuid(设置文件系统的用户识别码) 73 7.26 73 setgid(设置真实的组识别码) 73 7.27 73 setgrent(从头读取组文件中的组数据) 73 7.28 74 setgroups(设置组代码) 74 7.29 74 setpwent(从头读取密码文件中的账号数据) 74 7.30 75 setregid(设置真实及有效的组识别码) 75 7.31 75 setreuid(设置真实及有效的用户识别码) 75 7.32 75 setuid(设置真实的用户识别码) 75 7.33 76 setutent(从头读取utmp 文件中的登录数据) 76 7.34 76 utmpname(设置utmp 文件路径) 76 8.数据结构和算法篇 76 8.1 76 crypt(将密码或数据编码) 76 8.2 77 bsearch(二元搜索) 77 8.3 78 lfind(线性搜索) 78 8.4 79 lsearch(线性搜索) 79 8.5 80 qsort(利用快速排序法排列数组) 80 8.6 81 rand(产生随机数) 81 8.7 81 srand(设置随机数种子) 81 9 文件操作篇 82 9.1 82 close(关闭文件) 82 9.2 82 creat(建立文件) 82 9.3 83 dup(复制文件描述词) 83 9.4 83 dup2(复制文件描述词) 83 9.5 84 fcntl(文件描述词操作) 84 9.6 85 flock(锁定文件或解除锁定) 85 9.7 85 fsync(将缓冲区数据写回磁盘) 85 9.8 85 lseek(移动文件的读写位置) 85 9.9 86 mkstemp(建立唯一的临时文件) 86 9.10 86 open(打开文件) 86 9.11 88 read(由已打开的文件读取数据) 88 9.12 89 sync(将缓冲区数据写回磁盘) 89 9.13 89 write(将数据写入已打开的文件内) 89 10 文件内容操作篇 89 10.1 89 clearerr(清除文件流的错误旗标) 89 10.2 90 fclose(关闭文件) 90 10.3 90 fdopen(将文件描述词转为文件指针) 90 10.4 90 feof(检查文件流是否读到了文件尾) 90 10.5 91 fflush(更新缓冲区) 91 10.6 91 fgetc(由文件中读取一个字符) 91 10.7 91 fgets(由文件中读取一字符串) 91 10.8 92 fileno(返回文件流所使用的文件描述词) 92 10.9 92 fopen(打开文件) 92 10.10 93 fputc(将一指定字符写入文件流中) 93 10.11 94 fputs(将一指定的字符串写入文件内) 94 10.12 94 fread(从文件流读取数据) 94 10.13 95 freopen(打开文件) 95 10.14 95 fseek(移动文件流的读写位置) 95 10.15 96 ftell(取得文件流的读取位置) 96 10.16 96 fwrite(将数据写至文件流) 96 10.17 97 getc(由文件中读取一个字符) 97 10.18 97 getchar(由标准输入设备内读进一字符) 97 10.19 98 gets(由标准输入设备内读进一字符串) 98 10.20 98 mktemp(产生唯一的临时文件名) 98 10.21 99 putc(将一指定字符写入文件中) 99 10.22 99 putchar(将指定的字符写到标准输出设备) 99 10.23 99 rewind(重设文件流的读写位置为文件开头) 99 10.24 99 setbuf(设置文件流的缓冲区) 99 10.25 100 setbuffer(设置文件流的缓冲区) 100 10.26 100 setlinebuf(设置文件流为线性缓冲区) 100 10.27 100 setvbuf(设置文件流的缓冲区) 100 10.28 101 ungetc(将指定字符写回文件流中) 101 11 进程操作篇 101 11.1 101 atexit(设置程序正常结束前调用的函数) 101 11.2 101 execl(执行文件) 101 11.3 102 execlp(从PATH 环境变量中查找文件并执行) 102 11.4 102 execv(执行文件) 102 11.5 103 execve(执行文件) 103 11.6 104 execvp(执行文件) 104 11.7 104 exit(正常结束进程) 104 11.8 104 _exit(结束进程执行) 104 11.9 105 vfork(建立一个新的进程) 105 11.10 105 getpgid(取得进程组识别码) 105 11.11 106 getpgrp(取得进程组识别码) 106 11.12 106 getpid(取得进程识别码) 106 11.13 107 getppid(取得父进程的进程识别码) 107 11.14 107 getpriority(取得程序进程执行优先权) 107 11.15 108 nice(改变进程优先顺序) 108 11.16 108 on_exit(设置程序正常结束前调用的函数) 108 11.17 109 setpgid(设置进程组识别码) 109 11.18 109 setpgrp(设置进程组识别码) 109 11.19 109 setpriority(设置程序进程执行优先权) 109 11.20 110 system(执行shell 命令) 110 11.21 110 wait(等待子进程中断或结束) 110 11.22 111 waitpid(等待子进程中断或结束) 111 11.23 112 fprintf(格式化输出数据至文件) 112 11.24 112 fscanf(格式化字符串输入) 112 ... ... ... ...

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值