有没有办法强制相同的代码在Visual C++中生成相同的二进制文件?关闭PE中的时间戳或强制PE中的时间戳为某个固定值,换句话说?
c++ portable-executable visual-studio visual-c++ binary-reproducibility
我想在C#中实现这个
我看过这里:http: //www.codeproject.com/KB/cpp/PEChecksum.aspx
并且我知道ImageHlp.dll MapFileAndCheckSum函数.
但是,出于各种原因,我想自己实现.
我找到的最好的是:http: //forum.sysinternals.com/optional-header-checksum-calculation_topic24214.html
但是,我不明白这个解释.任何人都可以澄清如何计算校验和吗?
谢谢!
更新
我从代码示例中,我不明白这意味着什么,以及如何将其转换为C#
sum -= sum < low 16 bits of CheckSum in file // 16-bit borrow
sum -= low 16 bits of CheckSum in file
sum -= sum < high 16 bits of CheckSum in file
sum -= high 16 bits of CheckSum in file
Run Code Online (Sandbox Code Playgroud)
更新#2
谢谢,遇到了一些Python代码,不会太相似这里
def generate_checksum(self):
# This will make sure that the data representing the PE image
# is updated with …Run Code Online (Sandbox Code Playgroud) 我正在尝试用C++构建一个PE查看器,如果我尝试在Import Directory Table中输出库的名称,它似乎会崩溃.看来我没有得到程序使用的DLL的正确指针.
HANDLE handle = CreateFile("messagebox.exe",GENERIC_READ,0,0,OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,0);
DWORD size = GetFileSize(handle,NULL);
PVOID virtualpointer = VirtualAlloc(NULL,size,MEM_COMMIT,PAGE_READWRITE);
state = ReadFile(handle,virtualpointer,size,&byteread,NULL);
CloseHandle(handle);
PIMAGE_NT_HEADERS ntheaders = PIMAGE_NT_HEADERS(PCHAR(vpointer) +
PIMAGE_DOS_HEADER(vpointer)->e_lfanew);
handle = GetCurrentProcess();
DWORD EntryAddr = ntheaders->OptionalHeader.ImageBase +
ntheaders->OptionalHeader.AddressOfEntryPoint;
DWORD importdir =
(DWORD) &(ntheaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]);
DWORD va = (DWORD)(ntheaders->OptionalHeader.ImageBase) +
((PIMAGE_DATA_DIRECTORY)dwValueB)->VirtualAddress;
LPSTR libname[128];
int i =0;
while(((PIMAGE_IMPORT_DESCRIPTOR)dwValueC)->Name)
{
// get DLL name
libname[i] = (LPSTR)(nt->OptionalHeader.ImageBase +
((PIMAGE_IMPORT_DESCRIPTOR)dwValueC)->Name);
i++;
}
Run Code Online (Sandbox Code Playgroud) 在
http://en.redinskala.com/finding-the-ep/
有关于如何在exe文件中查找入口点的文件偏移量的信息.
在这里我可以读到这一点
EP(文件)= AddressOfEntryPoint - BaseOfCode + .text [PointerToRawData] + FileAlignment
但是,当我自己计算这个(我使用了几个不同的exe文件)时,我得出结论
EXE文件中入口点的偏移量= AddressOfEntryPoint + .text [PointerToRawData] - .text [VirtualAddress]
从IMAGE_OPTIONAL_HEADER获取AddressOfEntryPoint的位置和IMAGE_SECTION_HEADER中的其他两个值.
该网页上的信息是否为假?像它们一样添加FileAlignment似乎是错误的,它没有意义.或者是吗?文件对齐表明我应该使用modulo或其他东西来计算值.如果BaseOfCode和FileAlignment是相同的值(主要是它们),它不会干扰将它们添加到计算中,但它有什么意义呢?
好吧,所以我的想法是将64位和32位Windows可执行文件绑定到一个应用程序的某种方式,所以如果它不运行64位版本,它将尝试32位版本.
我正在阅读有关PE的内容,并了解了一些关于MS-DOS Real Mode Stub的内容,并说明了它如何调用应用程序(通常是错误消息).但每次我尝试研究MS-DOS Real Mode Stub时,它似乎只显示错误消息.所以我的想法是用我的32位应用程序覆盖STUB.
当32位操作系统运行64位可执行文件时,我自己很天真,它会失败,然后运行存根文件.
有没有办法让我的可执行程序32位/ 64位独立?
windows executable fat-binaries portable-executable 32bit-64bit
我正在编写驱动程序以创建防病毒程序。但是,我只能从进程中读取导入地址表。
我有一个CreateProcessNotify:
VOID CreateProcNotify(HANDLE ParentId, HANDLE ProcessId, BOOLEAN Create)
{
UNREFERENCED_PARAMETER(ParentId);
UNREFERENCED_PARAMETER(Create);
PEPROCESS Process;
KAPC_STATE Apc;
PVOID ModuleBase;
// From PID to PEPROCESS
PsLookupProcessByProcessId(ProcessId, &Process);
// Attach into the target process' memory
KeStackAttachProcess(Process, &Apc);
ModuleBase = GetModuleBase(Process);
PIMAGE_IMPORT_DESCRIPTOR pImportAddressTable = GetIAT(ModuleBase);
DPrint("Imports of [Meias] are: \n");
DPrint("IAT: %x\n", pImportAddressTable);
// Iterate all Modules Imports
while (pImportAddressTable->Name != 0) {
DPrint("{%s}, ", (PCHAR)((ULONG)ModuleBase + (pImportAddressTable->Name)));
pImportAddressTable++;
}
// Unattach ourselves from the target process' memory
KeUnstackDetachProcess(&Apc);
} …Run Code Online (Sandbox Code Playgroud) DLL 函数调用的地址修复是一个多阶段过程:链接器将调用指令定向到间接跳转指令,并将间接跳转指令定向到 Windows 程序加载器将放置的 .rdata 部分中的导入表中的一个内存字在运行时加载 DLL 时函数的地址。
间接跳转指令必须由链接器生成,因为编译器不知道该函数会出现在 DLL 中。通过为每个函数只生成一条间接跳转指令来最小化程序文件的大小,无论从多少地方调用它。
鉴于此,显而易见的方法是在所有目标文件中的所有编译器生成的代码之后收集文本部分末尾的所有间接跳转指令,这似乎是我尝试带有 Microsoft 链接器 /nodefaultlib 开关的简单测试用例(它生成一个足够小的可执行文件,我可以理解完整的反汇编)。
当我以正常方式将一个小程序与 C 标准库链接时,生成的可执行文件足够大,我无法跟踪所有的反汇编,但据我所知,间接跳转指令似乎分散在各处一次可能是三个小组的代码。
有没有我失踪的原因?
我知道PE是COFF的修改版,PE+是PE的64位支持的修改版,但是PEI是什么?我说 PE 和 PEI 之间没有区别并且它们可以互换使用是否正确?
windows ×4
c++ ×3
32bit-64bit ×1
algorithm ×1
assembly ×1
c ×1
c# ×1
checksum ×1
directory ×1
dll ×1
drivers ×1
entry-point ×1
executable ×1
fat-binaries ×1
file-format ×1
import ×1
linker ×1
visual-c++ ×1
windbg ×1