《加密与解密》学习笔记(三) - 脱壳

准备做第二个CrackMe的时候,涉及到了脱壳的知识,昨天看了一下午,今天又看了一点儿,把笔记贴在下面。昨天上午看了操作系统课程,浙江大学李善平老师讲的,希望不久可以学完。
12专用加密软件
	12.1.1 
		壳在源程序前面,加载内存中,先执行,对源程序解码,再交给系统加载
		防止静态反编译
		杀软能识别就直接脱壳检查病毒,不能识别就直接当病毒了
		常见壳有解压软件,很多都没有,手动脱壳很重要
	12.1.2
		压缩:保证压缩比前提下,压缩速度无所谓,解压一定要快,如aPlib,JCALG1,LZMA
	12.2压缩壳——重在减小软件体积的大小
		12.2.1UPX
			http://tpx.sourceforge.net
		12.2.2ASPack
			http://www.aspack.com
	12.3加密壳——越是有名的壳越容易被破解
		12.3.1ASProtect
			功能很强大,但是大家研究的也多
		12.3.2Armadillo//穿山甲
		12.3.3EXECryptor
		12.3.4Themida
	12.4虚拟机保护软件
		12.4.1保护机制
			把一直的x86指令根据自定义的指令系统解释称字节码,放到PE文件中,然后将原处代码删掉,进入虚拟机
			增加了解密者的分析成本,但是以效率换安全
			所以,一般提供SDK,可以只将关键的代码保护起来
		12.4.2VMProtect
			保护指定代码
			保护函数
			加密保护			
13脱壳技术
	13.1基础知识
		壳的加载过程
			HOOK-API//获取权限
			保存入口参数pushad/popad,pushfd/popfd
			获取壳自己所需要使用的API地址
				GetPorcAddress//加载DLL到内存
				GetModuleHandle//获取DLL句柄
				LoadLibrary//获取DLL中的函数地址
				有些人也自己写API与上面三个API的功能类似
			解密原程序的各个区块的数据(可以抓取内存映像文件)
				按区块加密,按区块解密
			IAT初始化
			重定位(DLL)初始化
			跳转到程序原入口点(OEP)
				一般壳在这有明显的分界线
				也有StolenBytes技术,使分界线不那么明显
		脱壳机
			专用脱壳机
			通用脱壳机
		手动脱壳
			寻找OEP
			抓取内存映像文件
			PE文件重建
	13.2寻找OEP
		根据跨段指令寻找OEP
			绝大多数PE加壳程序在被加密的程序中加上一个或多个区块,一步一步分析代码,壳程序执行完就能找到OEP
			代码样式(跨段跳转)
				push 00401300(目标指令的地址)
				retn
			经验:几个大段的程序,重点关注retn部分,有些值不会静态出现,往往需要运行到那一步才会出现
			经验:看到一个字节一个字节的代码,按ctrl+A重新分析一下
		根据内存访问断点寻找OEP
			OEP在.text,设置内存访问断点即可避免手动跟踪(第一个方法的替代)
			经验:一般的壳,处理顺序是.text,.rdata,.data,.rsrc先在别处设置内存访问断点,然后再在.text设置断点
			经验:重新开始/第一次载入,打断点,运行,再打断点,运行...最后一次断在OEP处。
			经验:查看内存,按F2打断点
		利用堆栈平衡寻找OEP
			壳程序一定会保存现场,会使用pushad和popad指令,初始栈顶为ESP1,pushad后栈顶为ESP2,
				对EPS2下硬件访问断点,即可断在OEP前面一点儿
			壳程序结束后,正常的程序一开始往往是压栈,在ESP1低一个字节下硬件写入断点,即可断在OEP后面一点儿
		利用常见语言的入口代码寻找OEP
			没看懂
	13.3抓取内存映像(Dump转存)
		一般来说,找到OEP,利用OllyDump插件即可(此无需再重建导入表)/LordPE全部转存(OEP需找到)
		Anti-Dump技术
			纠正SizeOfImage,LordPE右键进程可以修正,Ollydbg插件貌似自动修正了
			修改内存属性为不可读,LordPE右键区域转存查看哪个内存地址的权限被修改了,打开Ollydbg把权限改成全部访问
				再用LordPE全部转存,不用保存二进制文件,LordPE能检测出由Ollydbg装入内存的映像
	13.4重建输入表
		导入表和导入地址表机制略
		关键技术:通过导入地址表恢复导入表
			定位导入地址表
				随便找到一个调用API函数的指令,找到那块内存,hex区,长型->地址,查看更方便
			打开dump出的文件
				重建dll名和函数名/+100H
				重建IMAGE_THUNK_DATA/+E0H
				重建IMAGE_IMPORT_DECRIPTOR/+10H在IDT后面
				修改目录结构中的值,可用LordPE中的PE编辑器
			软件实现
				ImportREC
					目标文件已完全被Dump
					目标文件必须正在运行中
					已经找到OEP或者已知IAT的偏移或者大小
				ImportREC的使用略
				处理不连续IAT的方法略
				手工修复函数略
		加密的情况(外壳解压数据时:)
			导入表保留,IAT未被加密
				在内存映像文件刚刚生成时抓取,此时导入表还是好的//ASPack, PECompact
			导入表保留,IAT被加密(填写Hook-API)
				跳过加密的代码或者在未加密之前抓取//tElock
			导入表被破坏,IAT未被加密
				找到OEP,正常使用ImportREC
			导入表被破坏,IAT被加密(Hook-API)
				跳过加密或者在未加密之前抓取//ASProtect
			IAT被加密的,都可以用ImportREC的插件先破解试试
续
13.6附加数据
	补充PEid等Section Infomation
		VOffsetVSize内存对齐偏移和大小
		ROffsetRSize文件对齐偏移和大小
	检测
		利用PEid,如果显示Nothing found[Overlay]*,说明有附加数据
	脱壳
		正常脱壳后,将附加数据加到壳文件末尾,并修改读取附加数据的响应指针(SetFilePointer)
		这个API函数要在Dump.exe中招
13.7PE文件的有话
	导入表优化
		关键是把得到的导入表放到原来的节中,而不是令开辟新节
		不同的编译器的导入表的位置是不一样的,一般在.rdata导入地址表后面
		找到一块空白地址,ImportREC重建时输入这个地址
	资源优化
		关键是把资源弄回.rsrc中
		利用resfixer查看
		利用DT_resfix修正
		原理
			重排资源,设立新节
			修改PE头
	区块调整
		删除多余的壳节和资源节
		利用CFF explorer修正
		原理
			修正PE头,删除多余字节码
	修正PE头
		OEP
		BaseOfCode,代码节起始RVA(.text)
		BaseOfData,代码外的部分的其实RVA(.rdata)
		SizeOfImage
		//以上工具多会自动修正
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
你可以使用python的cryptography库来实现AES加密解密,以及使用zeropadding进行填充。 首先,你需要安装cryptography库。可以使用以下命令来安装: ``` pip install cryptography ``` 接下来,你可以使用以下代码示例来实现AES加密解密,并使用zeropadding进行填充: ```python from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes from cryptography.hazmat.primitives import padding from cryptography.hazmat.backends import default_backend import os def aes_encrypt(plain_text, key): # 生成一个随机的初始化向量 iv = os.urandom(16) # 使用zeropadding进行填充 padder = padding.ZeroPadding(128).padder() padded_data = padder.update(plain_text) + padder.finalize() # 创建AES加密器对象 cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=default_backend()) encryptor = cipher.encryptor() # 执行加密操作 cipher_text = encryptor.update(padded_data) + encryptor.finalize() return iv + cipher_text def aes_decrypt(cipher_text, key): # 提取初始化向量和密文 iv = cipher_text[:16] cipher_text = cipher_text[16:] # 创建AES解密器对象 cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=default_backend()) decryptor = cipher.decryptor() # 执行解密操作 padded_data = decryptor.update(cipher_text) + decryptor.finalize() # 使用zeropadding进行取消填充 unpadder = padding.ZeroPadding(128).unpadder() plain_text = unpadder.update(padded_data) + unpadder.finalize() return plain_text # 测试代码 key = os.urandom(32) # 生成一个随机密钥 plain_text = b"Hello, AES!" # 原始文本 # 加密 cipher_text = aes_encrypt(plain_text, key) print("Cipher Text: ", cipher_text) # 解密 decrypted_text = aes_decrypt(cipher_text, key) print("Decrypted Text: ", decrypted_text) ``` 这段代码中,我们使用了AES加密算法和CBC模式来加密解密数据。同时,我们使用了zeropadding进行填充,确保数据长度满足加密算法的要求。需要注意的是,密钥的长度必须符合AES算法的要求(16、24、或32字节)。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值