怎样用流读取写入DLL里面的字符串

vincent3 2004-11-03 05:31:29
我想往一个DLL的尾部写入一个字串,10个字符左右,然后能正常读出来

写入方法如下,能正确写入
var
Target:TFileStream;
S :String;
i :Integer;
begin
S := '32420B3E';
Target :=TFileStream.Create('TEST.dll', fmOpenWrite or fmShareExclusive);
try
i :=Sizeof(S)+sizeof(i);
Target.Seek(0,soFromEnd);
Target.WriteBuffer(s,Sizeof(s));
Target.WriteBuffer(i,sizeof(i));
finally
Target.Free;
end;
end;

读方法:
var
FCRC, S :String;
Source:TFileStream;
i :Integer;
begin
FCRC := GetCRC32(edtMain.Text);
Source := TFileStream.Create(edtDll.Text, fmOpenRead or fmShareDenyNone);
try
Source.Seek(0, soFromEnd);
Source.Read(i,Sizeof(i));
Source.Read(S,i-Sizeof(i));

if Pos(FCRC, S)=1 then
Information('测试成功')
else begin
Warning('测试失败,请检查');
end;
finally
Source.Free;
end;
end;
怎么读方法不对呢,应该怎样写,谢谢?
...全文
370 26 打赏 收藏 转发到动态 举报
写回复
用AI写文章
26 条回复
切换为时间正序
请发表友善的回复…
发表回复
vincent3 2004-11-05
  • 打赏
  • 举报
回复

我原来的代码
Target.WriteBuffer(FCRC,Length(FCRC));
应该改为
Target.WriteBuffer(FCRC[1],Length(FCRC));

谢谢alphax(无之心),你的代码风格不错,象我虽然知道Assert的用法,但至多会在写类时用到。

上面的封装如果用在检验CRC前还有个问题,就是要保证CRC码长度统一,最好要格式化为固定长度就OK了
alphax 2004-11-05
  • 打赏
  • 举报
回复
//我这里可以啊,你的问题可能在别的地方吧

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Buttons;

type
TForm1 = class(TForm)
btnVerify: TButton;
Edit1: TEdit;
btnSignature: TButton;
SpeedButton1: TSpeedButton;
OpenDialog1: TOpenDialog;
procedure btnVerifyClick(Sender: TObject);
procedure btnSignatureClick(Sender: TObject);
procedure SpeedButton1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

function VerifyStream(
FS: TStream;
const aSignature: string
): Boolean;
var
L: Integer;
Buf: string;
begin
Result := False;
L := Length(aSignature);
if (L > 0) and (FS.Size > L) then
begin
FS.Seek(-L, soFromEnd);
SetLength(Buf, L);
FS.ReadBuffer(Buf[1], L);
Result := CompareStr(Buf, aSignature) = 0;
end;
end;

procedure SignatureFile(const aFileName: string; const aSignature: string);
var
FS: TFileStream;
begin
Assert(aSignature <> '');

FS := TFileStream.Create(
aFileName,
fmOpenReadWrite or fmShareExclusive
);

with FS do
try
if not VerifyStream(FS, aSignature) then
begin
Seek(0, soFromEnd);
WriteBuffer(aSignature[1], Length(aSignature));
end;
finally
Destroy();
end;
end;

function VerifyFile(const aFileName, aSignature: string): Boolean;
var
FS: TFileStream;
begin
FS := TFileStream.Create(aFileName, fmOpenRead or fmShareDenyWrite);
try
Result := VerifyStream(FS, aSignature);
finally
FS.Destroy();
end;
end;

const
Signature = 'CRC TEST';

procedure TForm1.btnVerifyClick(Sender: TObject);
begin
if not VerifyFile(Edit1.Text, Signature) then
raise Exception.Create('The file is not signatured');

ShowMessage('ok');
end;

procedure TForm1.btnSignatureClick(Sender: TObject);
begin
SignatureFile(Edit1.Text, Signature);
end;

procedure TForm1.SpeedButton1Click(Sender: TObject);
begin
if OpenDialog1.Execute then
Edit1.Text := OpenDialog1.FileName;
end;

end.

vincent3 2004-11-05
  • 打赏
  • 举报
回复

真的不行呵,我把代码贴出来了,edtDll.text可以随便换成一个DLL的路径
procedure TMainFrm.acPackExecute(Sender: TObject);
var
FCRC :String;
Target:TFileStream;
begin
FCRC := GetCRC32;
Target :=TFileStream.Create(edtDll.Text, fmOpenWrite or fmShareExclusive);
try
Target.Seek(0,soFromEnd);
Target.WriteBuffer(FCRC,Length(FCRC));
finally
Target.Free;
end;
ShowMessage('SUCC');
end;

procedure TMainFrm.acTestExecute(Sender: TObject);
var
FCRC, Str :String;
Source:TFileStream;
begin
FCRC := GetCRC32;
Source := TFileStream.Create(edtDll.Text, fmOpenRead or fmShareDenyNone);
try
SetLength(Str, Length(FCRC));
Source.Seek(-Length(Str), soFromEnd);
Source.Read(Str[1], Length(Str));

if Pos(FCRC, Str)=1 then
ShowMessage('SUCC')
else begin
ShowMessage('FAILT');;
Caption := Str;
end;
finally
Source.Free;
end;
end;

function TMainFrm.GetCRC32: String;
begin
Result := 'CRC TEST';
end;
king20151111 2004-11-05
  • 打赏
  • 举报
回复
学习
nyf1220 2004-11-05
  • 打赏
  • 举报
回复
SetLength(Str, Length(FCRC));
Source.Seek(-Length(Str), soFromEnd);
Source.Read(Str[1], Length(Str));

这段改后应该没什么问题,有问题的话,也许你其他地方错了,仔细检查下,,
vincent3 2004-11-04
  • 打赏
  • 举报
回复
我在未尾就写了几个字符,写入后,那个DLL能用。
不过不能用也无所谓

关键是现在要怎样才能读出来,谢谢
ksaiy 2004-11-04
  • 打赏
  • 举报
回复
哦。那你写了以后DLL弄否用?

EXE文件你也可以直接写啊.但是就会破坏它的结构.
vincent3 2004-11-04
  • 打赏
  • 举报
回复

可以的,我写进去后,再LOAD那个DLL,能调用里面的方法

问题是现在应该怎样读出来?

谢谢
vincent3 2004-11-04
  • 打赏
  • 举报
回复
用了两个信箱发,都退回了,说地址有问题。

你忙就明天再弄了
alphax 2004-11-04
  • 打赏
  • 举报
回复
动不动就邮箱,真是的,你还要多多努力啊,
查查你的短信,我已经将我的邮箱通过论坛短信发给你了,不过尽量发主要的代码,我的邮箱下载很慢的,,,而且,要快,因为要下班回家了
vincent3 2004-11-04
  • 打赏
  • 举报
回复
新的也不行,读出来的东西是乱码

:)我是怀疑代码有问题,不过不知道怎么办?
程序很简单,就是一个写入,一个读出

你方便的留下邮箱,我发DEMO给你看看。
alphax 2004-11-04
  • 打赏
  • 举报
回复
我还漏说一个错的地方

Source.Seek(-Sizeof(Str),soFromEnd);
Source.Read(Str,Sizeof(Str));

应该改成
SetLength(Str, Length(FCRC));
Source.Seek(-Length(Str), soFromEnd);
Source.Read(Str[1], Length(Str));

这些代码是最基本的文件读写,出现你说的那种不稳定的问题,你应该首先怀疑你自己的代码有没有写对
vincent3 2004-11-04
  • 打赏
  • 举报
回复
就是按你说的改
但有BUG

有时进去,能测试成功,有时却测试失败,读出来的是FORM上面一个LABEL的CAPTION
改了那个标签,即有时第一次失败,以后都成功。
总之就是有点不稳定。不知有没有其它方法

谢谢
alphax 2004-11-04
  • 打赏
  • 举报
回复
怎么不行?把你的改成的样子帖出来先
vincent3 2004-11-04
  • 打赏
  • 举报
回复
还是不行
alphax 2004-11-04
  • 打赏
  • 举报
回复
代码错了,

Target.WriteBuffer(FCRC,Sizeof(FCRC)); //不要用SizeOf,用Length(FCRC)


Source.Seek(-Sizeof(Str),soFromEnd); //要用Length(str)

Source.Read(Str,Sizeof(Str));
//上面这句正确的应该是
SetLength(Str, Length(FCRC));
Source.Read(Str[1], Length(Str));


vincent3 2004-11-04
  • 打赏
  • 举报
回复

谢谢 ksaiy(消失在人海-喜欢昆明的花)
我就怕写入到DLL里面会破坏结构,但我现在测试过,写入后,能正常LOAD入并成功调用里面的函数
你讲到的方法我都知道
我真正写入时是会加密的
不用其它文件而用DLL就是想在主程序里面进行一次调用,如果被人家破坏了,自然调用不成功,当然,这样的检测也作用有限,不过想到了也无妨一用
至于在其它地方的校检,是有的。

也谢谢alphax(无之心) ,看了你的回应,我重新看了下代码
改成如下

//写入
var
FCRC :String;
Target:TFileStream;
begin
FCRC := GetCRC32(edtMain.Text);
Target :=TFileStream.Create(edtDll.Text, fmOpenWrite or fmShareExclusive);
try
Target.Seek(0,soFromEnd);
Target.WriteBuffer(FCRC,Sizeof(FCRC));
finally
Target.Free;
end;
end;


//读出
var
FCRC, Str :String;
Source:TFileStream;
begin
FCRC := GetCRC32(edtMain.Text);
Caption := FCRC;
Source := TFileStream.Create(edtDll.Text, fmOpenRead or fmShareDenyNone);
try
Source.Seek(-Sizeof(Str),soFromEnd);
Source.Read(Str,Sizeof(Str));

if Pos(FCRC, Str)=1 then
Information('测试成功')
else begin
Warning('测试失败,请检查');
Caption := Str;
end;
finally
Source.Free;
end;
end;

现在发现有个奇怪问题,当第一次调用读出方法时是失败的,读出的Str是其它东西,不过再一次或很多次调用都正确?
不知道什么原因
谢谢
alphax 2004-11-04
  • 打赏
  • 举报
回复
切,你的代码都没写对,当然错啦

Source.Seek(0, soFromEnd); //你已经移到末尾了,还读什么?
Source.Read(i,Sizeof(i));
Source.Read(S,i-Sizeof(i));
ksaiy 2004-11-04
  • 打赏
  • 举报
回复
你写到DLL里面会破坏它的结构,你写到DLL中没有加密,那你还不如写到一个文件(文件结构自己可以定义)里面啊,写进去的时候你可以放很多很多的无用的十六进制进去,然后把你的CRC校验值加密后写到文件里,但也不要写到一起,你可以分别写到不同的地方。调用的时候把规定地方的值读出来,然后加在一起进行加密再来对比,并且你在程序中比较的时候可以采用非明码的比较方式,并且CRC校验可以放到多个地方(这样防止脱壳以后跳一次就没有效果),比如功能比较重要的地方你还可以进行CRC校验等等。
nyf1220 2004-11-04
  • 打赏
  • 举报
回复
要不你写进去的时候,查看下,是否是写到了最后,或者DLL把你写的东西进行了调整。
加载更多回复(6)

5,388

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧