首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Delphi 7:函数在dll中调用时崩溃,在exe中工作

在Delphi 7中,如果一个函数在DLL中调用时崩溃,而在EXE中工作正常,这可能是由于以下原因导致的:

  1. 导出函数的问题:确保在DLL项目中导出函数时使用了正确的方法。在Delphi 7中,可以使用exports关键字导出函数。例如:
代码语言:txt
复制
library MyDLL;

uses
  SysUtils;

function MyFunction(param1: Integer; param2: String): Integer; export;
begin
  // 函数实现
end;

exports
  MyFunction;
  1. 内存管理问题:在DLL和EXE之间共享数据时,可能会出现内存管理问题。确保在DLL和EXE中使用相同的内存管理器。在Delphi 7中,可以使用sharemem单元来实现这一点。
  2. 参数传递问题:确保在DLL和EXE之间正确传递参数。例如,如果在DLL中使用了不同的数据类型,可能会导致崩溃。
  3. 平台和编译器差异:确保在DLL和EXE项目中使用相同的平台和编译器设置。例如,如果在DLL中使用了不同的字符集或调试选项,可能会导致崩溃。
  4. 动态链接库路径问题:确保在调用DLL时使用了正确的路径。如果DLL未找到或路径不正确,可能会导致崩溃。
  5. 其他依赖项问题:确保DLL和EXE项目之间的所有依赖项都正确配置。例如,如果DLL依赖于某个动态链接库或其他组件,需要确保这些组件在调用DLL时可用。

要解决这个问题,首先检查上述所有可能的原因,并相应地进行调整。如果问题仍然存在,请尝试在Delphi 7的官方支持论坛或社区中寻求帮助。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

  • Delphi中利用SEH屏蔽退出时的Runtime Error

    Delphi写的程序,如果在单元的finalization里出现了一些异常操作会导致退出时抛出Runtime Error ,规范的处理办法当然是解决这些异常,但是有些特殊的情况下,比如用了很多的第三方控件,实在没办法解决问题时,只有把他屏蔽掉,这样给客户的时候就不至于看到满天的Runtime Error 了。 做法其实很简单,就是在 END.之前手工调用Halt释放,并且将Halt抛出的错误屏蔽掉,这样做和正常的DELPHI释放过程没有任何区别,因为End.编译后其实就是一句话 Call Halt0,只是VCL自己没有屏蔽Halt0里抛出的错误,而是跳出个Runtime Error 来;   首先就是位置的问题,如果是EXE的话,直接在END.之前就行了,如果是Dll的话就麻烦点,需要挂上DllProc,当wReason = DLL_PROCESS_DETACH时处理。 然后就是如何屏蔽错误的问题了,第一个最容易想到的做法就是直接 Try  halt except end;   但是这样是不行的,因为try…except end捕获的错误都会放到System单元的_HandleOnException中处理,函数检查错误类型是否是DelphiException,如果不是就不处理,这个时候就会被DELPHI的顶层异常机制捕获,并抛出Runtime error,halt里抛出来的错误恰恰就是非DelphiException,代码如下:  procedure _HandleOnException; …   CMP [EAX].TExceptionRecord.ExceptionCode,cDelphiException   JE @@DelphiException   CLD   CALL _FpuInit   MOV EDX,ExceptClsProc   TEST EDX,EDX   JE @@exit    CALL EDX   TEST EAX,EAX   JNE @@common   JMP @@exit … End; 所以,需要借助SHE机制来处理这个问题,代码如下:   asm    //挂上SEH xor edx, edx    push ebp   push OFFSET @@safecode   push dword ptr fs:[edx]   mov fs:[edx],esp   //调用Halt0   call Halt0   jmp @@exit;   @@safecode:    //如果出现异常继续调用Halt0退出 call Halt0;   @@exit:  end; 这个做法的好处就是,不会对DELPHI正常释放过程产生影响,所有的释放操作都是和VCL一致的,只是不会把错误显示出来。 以下是完整代码: 一、EXE的情况,把代码放在工程文件 procedure Halt0; begin Halt; end; begin Application.Initialize; Application.CreateForm(TForm1, Form1); Application.Run; asm  xor edx, edx  push ebp  push OFFSET @@safecode   push dword ptr fs:[edx]  mov fs:[edx],esp   call Halt0  jmp @@exit;  @@safecode:   call Halt0;   @@exit: end; end.

    04

    N种内核注入DLL的思路及实现

    内核注入,技术古老但很实用。现在部分RK趋向无进程,玩的是SYS+DLL,有的无文件,全部存在于内存中。可能有部分人会说:“都进内核了.什么不能干?”。是啊,要是内核中可以做包括R3上所有能做的事,软件开发商们也没必要做应用程序了。有时,我们确实需要R3程序去干驱动做起来很困难或者没必要驱动中去做的事,进程 / DLL是不错的选择,但进程目标太大,所以更多的同学趋向于注DLL。 若要开发安全软件、小型工具,可借鉴其思路,Anti Rootkits时,在某些极端情况下,可使用同样的技术发现、清除RK,保证用户电脑的正常使用。在此,我将探讨几种内核注入DLL的思路及实现原理。 (1) APC技术 给一个Alertbale的用户态线程插APC,让其执行其中的ShellCode,来执行我们的代码。这个方法简单易行,但是不够稳定,兼容性不好。测试中发现经常出现Explorer.exe等插崩溃的情况,而且有杀软在的情况下,插入有时会被拦截,起不到应有的效果。(可参考我以前逆过的一个驱动:逆向fuck.sys--编译通过--源码) (2) 内核Patch [url=file://KnownDLLs/Kernel32.dll]\\KnownDLLs\\Kernel32.dll[/url] CreateThread [url=file://KnownDLLs/]\\KnownDLLs[/url]是系统加载时对象管理器加载最新磁盘DLL到内存的,当其他进程想调用某个DLL时,就不用重复从磁盘加载了,而会从这里映射一份到自己的进程空间中去。这样给我们做全局Patch提供了一个很好的机会: ZwOpenSection打开 [url=file://KnownDlls/kernel32.dll]\\KnownDlls\\kernel32.dll[/url],调用ZwMapViewOfSection映射一份到自己进程空间,然后寻找kernel32.dll在内存中代码节的空隙,选择这里作为我们fake函数的存储Buffer。修改CreateThread函数的开头5字节跳转到这个间隙,当系统任何一个线程创建时,会走到CreateThread函数,然后执行空隙中的ShellCode,其负责调用LoadLibrary加载我们的DLL。DLL一经加载,会发IOCTL通知本驱动,让驱动卸载HOOK。这样就完成了内核注DLL的过程。测试时发现Svchost.exe进程调用CreateThread函数很频繁,所以触发也会很快,基本1秒不到就能将DLL加载进去,而我们的HOOK也卸掉了。所以稳定性提高不少。示意图如下:

    02

    SpoolFool:Windows Print Spooler 权限提升 (CVE-2022-21999)

    早在 2020 年 5 月,微软就修复了一个 Windows Print Spooler 权限提升漏洞。该漏洞的编号为 CVE-2020–1048,微软承认 SafeBreach Labs 的 Peleg Hadar 和 Tomer Bar 报告了该安全问题。在补丁发布的同一天,Yarden Shafir和Alex Ionescu发表了关于该漏洞的技术文章。本质上,用户可以通过创建指向磁盘上文件的打印机端口来写入任意文件。在修补漏洞 (CVE-2020–1048) 后,Print Spooler 现在将在添加端口之前检查用户是否有权创建或写入文件。补丁和博文发布一周后,Paolo Stagno(又名 VoidSec)私下向微软披露了 CVE-2020–1048 的绕过方法。该绕过在三个月后的 2020 年 8 月得到修补,微软承认有八个独立实体报告了该漏洞,该漏洞被确定为 CVE-2020-1337。该漏洞的绕过使用目录连接(符号链接)来规避安全检查。假设用户创建了目录C:\MyFolder\并配置了一个打印机端口以指向该文件C:\MyFolder\Port。该操作将被授予,因为确实允许用户创建C:\MyFolder\Port. 现在,如果用户随后变成C:\MyFolder\指向C:\Windows\System32\创建端口之后的目录连接会发生什么?好吧,Spooler 会简单地写入文件C:\Windows\System32\Port。

    03

    VC++的DLL应用(含Demo演示)

    在大学大一的时候学的是C,然后后来大二的时候专业又开了C++这个课程,然后再后来自己又自学了一点VC++,大三的时候也试着编写过一个MFC的最简单的窗口程序。到大四的时候,自己又做了一个GIS的项目,是用C#.NET来编写的,然后发现C#上手好容易,而且还大部分语法规则都沿用了C,C++的习惯,于是觉得C++实在是没有一点优势可言啊。但这个暑假的实习经历又改变了我的观点:C++在写窗口程序虽然麻烦,但是却什么能做,而且对比C#来说,对运行环境的要求不高,不用像C#程序在安装之前还要安装100M多的运行.NET环境。C++和C#各有优缺,目前我对它们俩的定位是:C++用来写一些底层的程序,比如驱动,或者是一些算法类型的函数接口,然后用C#来调用这些接口并进行界面设计。如何函数的实现跨语言呢?显然DLL是个很重要的内容,故在此对VC++的DLL模块进行介绍。

    02

    Windows Redis DLL劫持在实战中的利用

    举例: 例如,假设有一个应用程序叫做"example.exe",它依赖于名为"example.dll"的动态链接库。而"example.exe"在加载"example.dll"时没有使用绝对路径,而是仅仅指定了DLL的名称。攻击者可以将恶意的"example.dll"文件放置在与"example.exe"相同的目录下,当"example.exe"启动时,系统会先在当前目录中查找"example.dll"文件,如果找到,就会加载该文件并执行其中的恶意代码。 DLL劫持可以函数转发劫持也可以往完整DLL插入恶意代码,这里用的函数转发劫持,大致流程如下图所示: https://kiwings.github.io/2019/04/04/th-DLL%E5%8A%AB%E6%8C%81/ 2.2 劫持dbghelp.dll redis-server.exe在执行bgsave时,会先在应用‍目录查找dbghelp.dll,找不到再去system32目录下找: 而不管redis的权限是Administrator还是普通用户或者Network Service,它对自己的应用目录一定有写文件的权限,我们可以通过Redis的主从复制在应用目录里写入恶意DLL。 2.3 函数转发劫持 对DLL进行函数转发劫持需要导出原本DLL的函数和地址,以保证程序通过恶意DLL调用这些函数时不影响正常功能,DLL的导出函数一般比较多,用Aheadlib之类的工具可以自动化处理。 我这里用的是DLLHijacker,它会自动处理导出表并生成一个VS2019的项目,但这个python脚本有几个bug: https://github.com/kiwings/DLLHijacker (1) VS项目中文乱码: 修复:几个写文件的地方添加 encoding="utf-8"。 (2) 函数导出表有匿名函数的时候,会导致以下报错 [-]Error occur: 'NoneType' object has no attribute 'decode 修复:在几个for循环里添加函数名是否为空的判断可以解决这个问题。 (3) 生成C/C++代码时,没有使用目标DLL的绝对路径,只是用了DLL的名字填充LoadLibrary(),这是一个很严重的bug,会导致函数转发失败、Redis的功能受到影响从而只能劫持一次: 修复:我改成了根据输入的目标DLL路径自动填充。 如果没有使用原DLL的绝对路径,在Process Monitor可以看到,只会调用应用程序目录里的恶意DLL,并没有调用原本的system32下的dbghelp.dll: 从而redis的功能受到影响,导致redis的bgsave只能触发一次DLL调用,第二次bgsave的进程会被阻塞从而无法调用DLL,并且Redis关闭后将无法启动: 这也是网上部分师傅的文章写”不会影响redis运行 但会无法重启“的原因,因为他们也是用的DLLHijacker,并且没有发现有这个坑,这不仅会影响业务,而且只能劫持一次: 正常的DLL劫持不会影响程序的功能,可以劫持很多次,假如我第一次劫持想上线CS但是没有成功,那对面可能不出网,那我可能会再劫持打一个MSF的反向shell,都没成功我也可以继续尝试MSF盲打命令: 正常的DLL转发劫持如下,调用完应用程序目录里的恶意DLL后会调用原DLL: 0x03 漏洞利用 3.1 工具使用 工具下载地址: https://github.com/P4r4d1se/dll_hijack 如是是Windows 64位的Redis DLL劫持的话,可以直接用里面的VS2022版的dbghelp项目。 其他要用我修改后的DllHijacker.py和目标DLL路径生成VS项目: python3 DLLHijacker.py C:\Windows\System32\dbghelp.dll 下载安装VS2022,只用勾C++桌面开发: https://visualstudio.microsoft.com/zh-hans/downloads 打开生成目录里的sln文件,因为原本是VS2019的项目所以会提醒你升级,选确定,不然得另外安装v142的编译组件才能编译VS2019的项目: 打开后在源文件的dllmain.app,修改里面的shellocde就行,其他不用改: 3.2 出网——Cobalt Strike 如果Redis主机直接出网,或者能通其他已经上线CS的出网主机,那直接上CS是最好的选择,CS生成C语言的payload: 源文件的dllmain.app里把payload替换进去,然后选Release x64,生成——生成解决方案: 然后主从复制将dbghelp.dll写过去并bg

    01
    领券