免杀笔记 ---> C语言

这次的更新可能有点慢,因为这段时间也比较忙,加上C语言还得和汇编结合,导致小编一个知识点总是得反复揣摩(太菜了),所以免杀的更新篇幅长度可能会达到两个月和三个月,但是小编能保证,只要你能看懂这些笔记,那么我包你能过360的!!!

1.空函数的实现

我们在平时写c或者c++的代码的时候,不知道大家有没有想过,如果我们直接写这样的代码会怎么样?   难道编译器会啥都不干吗??? 

那当然不会的,我们一起来从汇编的角度来分析一下 (这里建议大家先生成×86的程序)

在进入函数之前,因为我们没有参数的传递,所以我们不用PUSH任何东西

然后我们就会将返回地址 00C713E3压入到堆栈里面,并且ESP加四。 过程如下

然后先是提栈操作

然后就是保留现场

然后就是填充缓冲区和实现函数的功能,但是由于我们是空函数,所以这两步骤就没有了

然后就是到了我们的还原现场的操作了

先把三个寄存器POP出去

然后就是快速降低堆栈(ESP的值)

然后直接POP了EBP的值(其实我这里说的不太准确,因为这里EBP的值是一块地址),而不是我们平时存的数值

然后POP完之后就变了这样(这一步两个寄存器都在改变

最后ret,将00C717E3的值给到EIP,并且压栈,函数返回(这里其实一开始说错了,call的时候压的是00C717E8,我当时看错了,以为是test函数下面的地址就是汇编返回下一行的地址,不过过程没有任何问题!!!堆栈刚好平衡

2.手搓一个裸函数

讲完了空函数,我们就要讲裸函数了,我们都是学计算机底层的,怎么可能想让编译器给我写代码,所以我们就想能不能自己在VS上手写一个裸函数,内容要我们自己实现!!!

  在写裸函数之前,我们还得先写上这样的代码

void __declspec(naked)test()
{
	__asm
	{

	}
}

有了上面的代码我们就可以自己写一个函数出来了,我们就以两数相加为例子把!! 对于一个裸函数,我们可以按照下面这几个步骤进行!!!

1.提栈

其实说这样提栈还不准确,应该说想Push了一些参数入栈,然后Call了才进入我们的函数

以下都是进函数之前的操作

然后才真正的到我们的提栈

2.保留现场

然后就是我们的保留现场了,依次压入我们的寄存器

3.填充缓冲区

聪明的你们一定发现了ESP和EBP之间还存在一大片空隙,那么我们现在就来填充缓冲区

但是在写缓冲区之前,我们还需要来看一条指令

这条指令的意思就是将EAX的寄存器的值循环写ECX次

所以我们的汇编就可以这么写

先把缓冲区起始位置mov给edi(虽然我不理解这一步的实际用处),然后就是将eax的值赋为0xcccccccc,ecx的值赋为0x10 ,然后直接循环填充缓冲区

4.实现函数功能

比如说我想实现 b = a + b   其中函数的传入为 (int a , int b )这两个参数位置不能调换(否则对应的指令也要换,这个后面讲)

5.还原现场

然后就是将对应寄存器POP出去

然后就是降低堆栈

并且同时改变两个寄存器!!!

最后就是RET,将返回地址给到EIP,跳回main函数

但是这时候聪明的你就会发现问题了,堆栈不平衡!!!!! 别急我们先运行一下

发现代码成功的跑了起来

我们去看反汇编,就能发现,原来是vs帮我们在自动的函数外面平栈

这步 add esp8就显得很精髓

所以我们的最终就达到了堆栈的平衡,成功手搓了一个裸函数,看,我们最简单的一个a+b的功能也是如此的多步骤呢,在汇编中

源代码如下

#include<stdio.h>

void __declspec(naked)test(int a,int b)
{
	__asm
	{
	//1.提栈
		push ebp
		mov  ebp ,esp
		sub  esp ,0x40
	//2.保留现场
		push ebx
		push esi
		push edi
	//3.填充缓冲区
		lea edi ,dword ptr ds:[ebp - 0x40]
		mov eax ,0xcccccccc
		mov ecx ,0x10
		rep stosd 
	//4.实现函数功能
		mov eax , dword ptr ds:[ebp + 0x8]
		add eax , dword ptr ds:[ebp + 0xc] 
     // mov dword ptr ds:[ebp + 0xc],eax  
		          
	//5.还原现场
		pop edi
		pop esi
		pop ebx 
		mov esp ,ebp
		pop ebp
		retn
	}
}

int main()
{

	test(2,3);
 	return 0;

}

其中我对一行进行了注释,因为我觉得这段代码是开放的,你也完全可以把他直接存在EAX然后retn回函数之后再对你想要赋值的东西进行赋值(非裸函数的VS编译器就是这么干的)

mov dword ptr ds:[ebp + 0xc],eax  

3.调用约定

上面我们说的是外平栈,其实默认的就是这样的调用

double __cdecl test(double a, double b)
{
	return a + b;
}

直接在函数外面进行平栈 

那么如果我们想要内平栈呢??? 那么就要这么写了

int   __stdcall test2(int  a, int  b)
{
	return a + b;
}

他直接Ret8了,其实这个指令就是add esp8 ,然后再retn

然后,就是我们的__fastcall了,这个函数于其他两个函数的区别,他在只有两个参数的情况下是不会对栈进行操作的,而是直接存储在CPU中,这样速度会快很多。

而且还要注意的一点,不知道大家发现没有,我们Push数进栈的时候,是从右往左进行PUSH的,而不是从左往右进行PUSH的!!!!

4.条件语句

首先就是我们的if了,我们先去写一段IF的代码

IF

    int i = 1;
	if (i == 1)
	{
		i = 2;
	}

然后我们直接去看它的反汇编

我们从上面就能发现,里面的JCC语句和现实逻辑其实是相反的,cmp如果相等的话ZF位就是1,

我们就能看见它的JCC语句是在如果两个数不相等的时候就会跳转,如果相等就会执行下面的语句

IF ELSE

既然有IF ,那怎么能少的了IF ELSE 呢

我们从汇编的角度不难发现,首先他是通过CMP判断,如果不是的话,JCC语句就跳到ELSE的位置,如果是的话,执行完cout之后他就会JMP到ELSE执行完毕

While

然后就是while了,我们还是通过写一段While代码进行看他的反汇编

我们还是能从反汇编里面看见je这个语句,其实就是Jump if zero,但是我们的test eax ,eax这个汇编语句是恒为真的,所以一定不会Jump!!!!就达到了一直循环的目的。

For

然后就是我们常用的for语句了

我们可以看见执行之前的JG这个JCC语句,它的意思是对于有符号数来说,如果大于则跳转,很明显,一开始我们的i都是小五5的,所以肯定是不会跳转的。

5.DLL

DLL (Dynamic Link Library) 文件为动态链接库文件,又称“应用程序拓展”,是软件文件类型。在Windows中,许多应用程序并不是一个完整的可执行文件,它们被分割成一些相对独立的动态链接库,即DLL文件,放置于系统中。当我们执行某一个程序时,相应的DLL文件就会被调用。一个应用程序可使用多个DLL文件,一个DLL文件也可能被不同的应用程序使用,这样的DLL文件被称为共享DLL文件。

当我们程序执行的时候,必须连接到DLL文件,然后通过DLL文件去调用一些Windows的API(像什么 WirteProcessMemory ,VirtualAlloc,CreateThread ......)

说了那么多,我们去VS生成一个DLL文件

生成之后我们能看见这样的东西

重点其实就在这串代码

  switch (ul_reason_for_call)
  {
  case DLL_PROCESS_ATTACH:
  case DLL_THREAD_ATTACH:
  case DLL_THREAD_DETACH:
  case DLL_PROCESS_DETACH:
      break;
  }
  • DLL_PROCESS_ATTACH :这个事件在当前进程第一次装载该 DLL 时触发,即 DLL 被加载到进程的地址空间中时。在这个分支中,可以执行与 DLL 装载相关的初始化操作。
  • DLL_THREAD_ATTACH    :这个事件在新线程创建并且该 DLL 被加载到新线程的地址空间时触发。在这个分支中,可以执行与新线程相关的初始化操作。
  • DLL_THREAD_DETACH    :这个事件在线程退出时触发,如果该线程加载了该 DLL,则会在 DLL 从该线程的地址空间中卸载时触发。在这个分支中,可以执行与线程退出相关的清理操作。
  • DLL_PROCESS_DETACH  :这个事件在当前进程卸载该 DLL 时触发,即该 DLL 从进程的地址空间中移除时。在这个分支中,可以执行与 DLL 卸载相关的清理操作。

那么下面我们就来演示一下DLL的调用方法,我么这里写一个弹窗的DLL

// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "pch.h"

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
        MessageBox(0, L"我是黑客", L"没有绝对安全的系统", MB_OK);
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }

    return TRUE;
}

然后我们去生成一下,并且通过工具,注入一个32位的程序(32位的DLL要注32位的EXE)

这里说一下 VS编译的快捷键是 Control + F7 

然后我们直接找一个EXE去注入,这里我就找一个自己写的EXE去注入了

然后就能看见弹框了

当然了,除了这种注入的方式去运行DLL,我们还可以去通过专门运行DLL的程序去运行

比如说rundll32就是一个不错的选择,不过被杀软盯得很严重,所以一般实战不会用这个,但是还是讲一下怎么使用!!!!

rundll32.exe custom.dll,CustomFunction

通过上面的命令,我们可以调用DLL里面的函数

#include <Windows.h>
extern "C" __declspec(dllexport) void rundll(HWND hwnd,HINSTANCE hinst,LPTSTR
lpCmdLine,INT nCmdShow)
{
MessageBox(NULL,TEXT("whoami"),TEXT("Rundll32"),MB_OK);
}
rundll32 testdll.dll, rundll 

 通过这个,我们的DLL中的函数也是能被加载进来的

那么,c语言的基础就到这里了,我后面就把Shellcode loader给补上

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/734504.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

RabbitMQ高频面试题整理

文章目录 1、RabbitMQ如何保证消息不丢失1&#xff09;confirm 消息确认机制 (生产者)2&#xff09;消息持久化机制 (RabbitMQ 服务)3&#xff09;ACK 事务机制(消费者) 2、RabbitMQ 中有哪几种交换机类型?1&#xff09; Direct Exchange2&#xff09;Fanout Exchange3&#x…

Netty 入门实例

文章目录 1. 概述2. 代码实例2.1 服务端2.2 客户端2.3 运行截图 3. 整体结构4. 重要组件4.1 EventLoopGroup、EventLoop4.2 Handler & Pipeline4.3 ByteBuf 参考文献 1. 概述 Netty 是一款用于高效开发网络应用的 NIO 网络框架&#xff0c;它大大简化了网络应用的开发过程…

【物联网】室内定位技术及定位方式简介

目录 一、概述 二、常用的室内定位技术 2.1 WIFI技术 2.2 UWB超宽带 2.3 蓝牙BLE 2.4 ZigBee技术 2.5 RFID技术 三、常用的室内定位方式 3.1 信号到达时间 3.2 信号到达时间差 3.3 信号到达角 3.4 接收信号强度 一、概述 GPS是目前应用最广泛的定位技术&#xff0…

流行的app抓包工具详解和案例--开发人员首选

个人名片 &#x1f393;作者简介&#xff1a;java领域优质创作者 &#x1f310;个人主页&#xff1a;码农阿豪 &#x1f4de;工作室&#xff1a;新空间代码工作室&#xff08;提供各种软件服务&#xff09; &#x1f48c;个人邮箱&#xff1a;[2435024119qq.com] &#x1f4f1…

游戏大厂“脱钩”安卓商店: 独立渠道TapTap们能否渔利

一纸公告将游戏厂商与渠道的博弈再度摆上了台面。 近日&#xff0c;腾讯控股旗下手游《地下城与勇士&#xff1a;起源》&#xff08;下称“DNF手游”&#xff09;运营团队发布公告称&#xff0c;自6月20日起&#xff0c;DNF手游将不再上架部分安卓平台的头部应用商店。 下架的…

Unity踩坑记录

1. 如果同时在父物体和子物体上挂载BoxCollider&#xff0c;那么当使用&#xff1a; private void OnTriggerEnter2D(Collider2D collision){if (collision.CompareTag("CardGroup")){_intersectCardGroups.Add(collision.GetComponent<CardGroup>());}} 来判…

WebStorm 环境配置带@符号的相对路径穿透

在使用WebStorm 环境开发web页面项目时有时想快速查看页面的引用代码&#xff0c;只能手工找到引入文件路径&#xff0c;这很不方便&#xff0c;只需通过配置webStorm单击打开。 1 使用符号相对路径&#xff0c;在默认情况下没有配置环境是无法打开&#xff0c;如下图&#xf…

docker内apt-get update Waiting for headers 0%

问题描述 docker运行debian等容器时&#xff0c;执行apt update或者apt-get update&#xff0c;可能会出现以下错误&#xff1a;root754a91d3630a:/# apt-get update 0% [Waiting for headers] [Waiting for headers] [Connected to developer.download.nvidia.com (152.199.3…

yolov8环境搭建+训练自己数据集

一、yolov8环境搭建 1. 安装miniconda环境 地址&#xff1a;https://mirrors.tuna.tsinghua.edu.cn/anaconda/miniconda 选择Python3.8版本 最好安装在C盘 勾选自动添加环境变量 ***以下操作安装过程中关闭代理软件 *** 2. 创建虚拟环境 conda create -n yolov8 python3…

Axios-入门

介绍 Axios对原生Ajax进行了封装&#xff0c;简化书写&#xff0c;快速开发 官网&#xff1a;Axios中文文档 | Axios中文网 (axios-http.cn) 入门 1引入Axios的js文件 <script src"js/axios.js"></script> 2使用Axios发送请求&#xff0c;并获取响应…

代理的匿名级别有哪些?为什么匿名性很重要?

在互联网时代&#xff0c;代理服务器在许多领域都扮演着重要的角色。无论是个人用户还是企业&#xff0c;都可能需要使用代理来保护自己的隐私和数据安全。在选择代理服务时&#xff0c;匿名级别是一个重要的考虑因素。本文将介绍代理的匿名级别&#xff0c;并解释为什么匿名性…

PDF转成清晰长图

打开一个宝藏网址在线PDF转换器/处理工具 - 在线工具系列 点击图下所示位置 按照图下所示先上传文件&#xff0c;设置转换参数后点击转换&#xff0c;等待 等待转换完成后&#xff0c;可以在转换结果处选择下载地址&#xff0c;点击即可进行下载使用了。对比了其他几个网站的转…

K8S -理解StatefulSet - 部署有状态应用

什么是 有状态服务和 无状态服务 有状态服务&#xff08;Stateful Service&#xff09;&#xff1a; 有状态服务是指在处理请求期间维护和跟踪用户状态或会话信息的服务。这意味着服务在多个请求之间保持状态&#xff0c;并且需要在请求之间共享和使用这些状态信息。通常&…

网络安全-如何设计一个安全的API(安全角度)

目录 API安全概述设计一个安全的API一个基本的API主要代码调用API的一些问题 BasicAuth认证流程主要代码问题 API Key流程主要代码问题 Bearer auth/Token auth流程 Digest Auth流程主要代码问题 JWT Token流程代码问题 Hmac流程主要代码问题 OAuth比较自定义请求签名身份认证&…

Spring Boot集成Minio插件快速入门

1 Minio介绍 MinIO 是一个基于 Apache License v2.0 开源协议的对象存储服务。它兼容亚马逊 S3 云存储服务接口&#xff0c;非常适合于存储大容量非结构化的数据&#xff0c;例如图片、视频、日志文件、备份数据和容器/虚拟机镜像等&#xff0c;而一个对象文件可以是任意大小&…

Vue38 安装脚手架 vue-cli ,并使用脚手架创建项目

安装脚手架 vue-cli &#xff0c;并使用脚手架创建项目 第一步 安装脚手架 npm config set registry https:\\[registry.npmmirror.com // 切换淘宝镜像 npm install -g vue/cli第二步 切换到创建项目的目录&#xff0c;创建项目 cd XXX vue create XXX第三步 启动项目 npm…

FreeCAD中智能指针分析

实现原理 FreeCAD中有两套智能指针&#xff0c;一个是OCC的智能指针handle&#xff0c;另一个是自己定义的智能指针Reference&#xff0c;两种智能指针都是通过引用计数方式管理指针。 1.1 OCC智能指针handle OCC在基础类包中定义了一个模板类handle&#xff0c;该类包含一个私…

购买服务器,并安装宝塔

前言&#xff1a; 我们在开发项目时&#xff0c;总会遇到一个问题&#xff0c;就是将我们开发好的项目上传的公网中。对于中小型的项目&#xff0c;我们可以通过购买服务器进行项目的上线。 我们的项目一般是部署在Linux环境中。如果你不是专业的运维人员&#xff0c;可能对于…

力扣1901.寻找峰值II

力扣1901.寻找峰值II 二分每一行 并用函数找出每一行中最大值的下标若最大值比其下面相邻的元素大 则上方一定存在峰值若最大值比其下面相邻的元素小 则下方一定存在峰值 class Solution {int indexmax(vector<int> &a){return max_element(a.begin(),a.end()) - …

解决js打开新页面百度网盘显示不存在方法:啊哦,你所访问的页面不存在了。

用js打开新页面open或window.location.href打开百度网盘后都显示&#xff1a;啊哦&#xff0c;你所访问的页面不存在了。 window.open(baidu_url); window.location.href baidu_url;在浏览器上&#xff0c;回车后网盘资源是可以打开的&#xff0c;刷新也是打开的。这是很奇怪…