举个例子如:我想把一个字符串hello,china 动态的保存到dll中,下次调用dll的时候取出来字符串就是hello,china。
不要告诉我没有办法达到,或者说建议保存到ini,注册表。。这类的话
最好有实例代码!
不要告诉我没有办法达到,或者说建议保存到ini,注册表。。这类的话
最好有实例代码!
解决方案 »
- 大富翁又可以访问了
- Fastreport 如何做交插表?
- ADOQuery1状态判断
- ADOCONNECTION TIMEOUT 问题
- SkinEngine是怎麼用的,請教了。
- 程序分发的问题?
- Quick Report 会出错?----stream write error!解决问题给高分
- 请问那位能找到csdn离线浏览器的源程序,能不能发一个给我谢谢
- 有一个foxpro的数据库,数据表全部存在db目录里,现在想用database控件建立数据连接,请问如何配置里面的参数?
- Socket通讯问题!!!求救!!!
- MDI子窗口如何在在主窗体工作区域内布满?
- IP4000 wwDBGrid 数据导出为 excel 问题
//主调
type
TWriteFile=procedure(Section:string;KeyWord:string;Value:string);stdcall;procedure Test;
var
DllHnd: THandle;
WriteIni: TWriteFile;
begin DllHnd := LoadLibrary(PChar('project1.dll'));
try
if (DllHnd <> 0) then
begin
@WriteIni :=GetProcAddress(DllHnd, 'WriteFile');
if (@WriteIni<>nil) then
WriteIni('abc','cde','Hello World');//INI文件的格式,最后一个为自定义的字符串
else
begin
application.MessageBox(PChar('DLL加载出错,DLL可能不存在!'), PChar('错误'),
MB_ICONWARNING or MB_OK);
end;
end;
finally
FreeLibrary(DllHnd);
end;
end;
//DLL
procedure WriteFile(Section:string;KeyWord:string;Value:string);stdcall;
{
功能:向qc.ini特定字段中写数据
}
var
qc_ini:Tinifile;
filename:string;
begin
filename:= ExtractFilePath(paramstr(0))+'qc.ini';
qc_ini := Tinifile.Create(filename);
qc_ini.WriteString(Section,KeyWord,Value);
qc_ini.Free;
end;exports
WriteFile;
楼主可以在dll文件末尾加一块数据段,往里面写,可以参考网上exe文件写自己的做法
一种方法是添dll"空隙"
另一种就是以流的方式在dll末尾追加数据
谁给我这两种方法分别写个例子
这种方式可以吗?
这种方式可以吗?值可以动态修改保存?
另一种就是以流的方式在dll末尾追加数据
谁给我这两种方法分别写个例子
res.rc
中是这样的
StringTable
begin
1000 ,"AAAA"
1001 ,"BBBB"
1002 ,"CCCC"
1003 ,"DDDD"
endfunction readSource(loadFile:PChar;var str:string):Boolean;
var
hres:THandle;
hexe:THandle;
hload:THandle;
pCResLock:PChar;
begin
Result:=False;
hexe:=LoadLibrary(loadFile);
if hexe>0 then
begin
hres:=FindResource(hExe,'1000',RT_STRING);
if hres>0 then
begin
hload:=LoadResource(hexe,hres);
if hload>0 then
pCResLock:=LockResource(hload);
str:=string(pCResLock);
Result:=True;
end; end;
FreeLibrary(hexe);end;function updateSource(loadFile:PChar;str:string):Boolean;
var
hUpdateRes:THandle;
begin
Result:=True;
hUpdateRes:=BeginUpdateResource(loadFile,False);
Result:=UpdateResource(hUpdateRes,
RT_STRING,
PChar('1000'),
MakeWord(LANG_NEUTRAL,SUBLANG_NEUTRAL),
PChar(str),
Length(str)
);
if Result=True then
EndUpdateResource(hUpdateRes,FALSE);
end;
procedure TForm1.btn2Click(Sender:TObject);
var
begin
readSource('D:\delphiDemo\Dll\DllRes.dll',s);
end;
procedure TForm1.btn2Click(Sender:TObject);
var
begin
updateSource('D:\delphiDemo\Dll\DllRes.dll','hello');
end;
操作都没有成功,帮忙看看是啥原因?
to hhero0773:
能给写个例子看看吗?多谢!
[code=BatchFile]MYRC RCDATA
begin
"Test\0"
end[/code]
function updateSource(loadFile:PChar;str:string):Boolean;
var
hUpdateRes:THandle;
begin
Result:=True;
hUpdateRes:=BeginUpdateResource(loadFile,false);
Result:=UpdateResource(hUpdateRes,
RT_RCDATA,
PChar('MYRC'),
MakeWord(LANG_NEUTRAL,SUBLANG_NEUTRAL),
PwideChar(str),
Length(str)
);
if Result=True then
EndUpdateResource(hUpdateRes,false);
end;
你的写的这种方式,是在rc资源区重新添加了test,不是把test改成别的东东?
你好,你说的这几种方式,理论上也明白了,但是在delphi中写个例子老实失败!很郁闷哦!你能给写个简单的例子吗?
ArrFuck: array[0..47] of Byte = (
$46, $55, $43, $4B, $46, $75, $63, $6B, $20, $79, $6F, $75, $72, $20, $70, $75,
$73, $73, $79, $21, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00); 数组前4位为我上面说的标记:'F', 'U', 'C', 'K' ,也就是FUCK这个词,方便我们后面自己找这个数组。数组后面的都是为0的空位,供你放数据的。我这里随便放一句话:Fuck your pussy! 16个字节。
然后程序里面至少有一个地方要调用下这个数组,否则数组没使用会被编译器忽略掉的,那就白花功夫了。procedure TForm1.FormCreate(Sender: TObject);
begin
ArrFuck[47] := $00; //Just use this fucking array
end; 把这个Demo.exe自己复制成一个新文件Fuck.dll,然后我们就开始用Demo.exe调用Fuck.dll自己中的这个缓冲区:procedure TForm1.Button1Click(Sender: TObject);
var
Ms: TMemoryStream;
i, Len: Integer;
C: Char;
Buf1: array[0..3] of Char;
Buf2: array[0..15] of Char;
Str: string;
begin
Ms := TMemoryStream.Create;
try
Ms.LoadFromFile('H:\Project\Fuck.dll');
Len := Ms.Size; for i := 0 to Len do
begin
Ms.Seek(i, soFromBeginning);
Ms.Read(C, 1);
if Ord(C) = $46 then
begin
Ms.Seek(i, soFromBeginning);
Ms.Read(Buf1, 4);
if (Ord(Buf1[1]) = $55) and (Ord(Buf1[2]) = $43) and (Ord(Buf1[3]) = $4B) then //Got it!
begin
Ms.Seek(i + 4, soFromBeginning);
Ms.Read(Buf2, 16);
SetLength(Str, 16);
Move(Buf2[0], Str[1], 16); ShowMessage('Cache Offside: ' + IntToHex(i, 8) + #13#10#13#10 +
'Cache Data: ' + Str); //Now you can write some bullshit into this cache
end;
end;
end;
finally
FreeAndNil(Ms);
end;
end; 找到后得到偏移量和写入的Fuck your pussy!这句话,当然,你自己可以随便写入什么都可以。
var
ArrFuck: array[0..47] of Byte = (
$46, $55, $43, $4B, $46, $75, $63, $6B, $20, $79, $6F, $75, $72, $20, $70, $75,
$73, $73, $79, $21, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00); procedure TForm1.FormCreate(Sender: TObject);
begin
ArrFuck[47] := $00; //Just use this fucking array
end;procedure TForm1.Button1Click(Sender: TObject);
var
Ms: TMemoryStream;
i, Len: Integer;
C: Char;
Buf1: array[0..3] of Char;
Buf2: array[0..15] of Char;
Str: string;
begin
Ms := TMemoryStream.Create;
try
Ms.LoadFromFile('H:\Project\Fuck.dll');
Len := Ms.Size; for i := 0 to Len do
begin
Ms.Seek(i, soFromBeginning);
Ms.Read(C, 1);
if Ord(C) = $46 then
begin
Ms.Seek(i, soFromBeginning);
Ms.Read(Buf1, 4);
if (Ord(Buf1[1]) = $55) and (Ord(Buf1[2]) = $43) and (Ord(Buf1[3]) = $4B) then //Got it!
begin
Ms.Seek(i + 4, soFromBeginning);
Ms.Read(Buf2, 16);
SetLength(Str, 16);
Move(Buf2[0], Str[1], 16); ShowMessage('Cache Offside: ' + IntToHex(i, 8) + #13#10#13#10 +
'Cache Data: ' + Str); //Now you can write some bullshit into this cache
end;
end;
end;
finally
FreeAndNil(Ms);
end;
end;
你写什么进去都行,不过别想隐藏什么,在调试器下面一切都是裸奔。如果你加壳,可能会把RCDATA压缩掉,那就找不到这个数组了,那就用别的方法比如把此数组嵌入壳中。
Run this demo
View with Hex Editor觉得还行就给分吧,呵呵
Dll被加载后是无法继续写操作的。你可以从上次编译结果中预先得到标记的大致偏移量,读取时直接从附近开始查找,速度很快。
这些都不是我需要解决的问题,我只是给出一个简单的例子,具体怎么去完善,每人自然会有不同的方法。想让标识唯一,估计有上千种方法:Hash, GUID, 非线性伪随机数…… 连SHA 512都有碰撞的可能性,何必奢求标识绝对性的唯一呢?只要能在这个小小的PE文件中间唯一即可。
中是这样的
StringTable
begin
1000 ,"AAAA"
1001 ,"BBBB"
1002 ,"CCCC"
1003 ,"DDDD"
end
我就是要修改1000 ,"AAAA" 为 1000 ,"test"
即
StringTable
begin
1000 ,"test"
1001 ,"BBBB"
1002 ,"CCCC"
1003 ,"DDDD"
end
没有添加到想要的地方读起来还是问题哦!
Fuck your pussy!改成 hello,china!保存在dll 中,然后下次读取是hello,china!而不是Fuck your pussy! 又如何操作!
代码没看懂吧?注释里有 Now you can write some bullshit into this cache. 找到4个字节标记的偏移量后直接把你的字符串比如"Hello, China!"写入Cache覆盖掉"Fuck your pussy!", 不足的写0。记住要从ArrFuck[4]开始往后写,不要把标记覆盖了,要不下次找不到了。
if (Ord(Buf1[1]) = $55) and (Ord(Buf1[2]) = $43) and (Ord(Buf1[3]) = $4B) then //Got it!
begin
Ms.Seek(i + 4, soFromBeginning);
Ms.Read(Buf2, 16);
SetLength(Str, 16);
Move(Buf2[0], Str[1], 16); ShowMessage('Cache Offside: ' + IntToHex(i, 8) + #13#10#13#10 +
'Cache Data: ' + Str); //Now you can write some bullshit into this cache
end;
如果你的数据不太长,也可以干脆写入到PE文件的0x80h,可以写128字节。
这个例子在Mastering borland delphi2005第十一章。
delphi不能像vc那样在dll中直接导出数据,必须借助第三方媒介吧。
个人理解。不对请指出来。
http://harryfin.spaces.live.com/blog/cns!31E57C5D97ECDF5!443.entry
StringTable
begin
1000 ,"test"
1001 ,"BBBB"
1002 ,"CCCC"
1003 ,"DDDD"
end
这个stringtable里的数据到可以,但是更新却不行,不知道你自己试过没有?
这个例子在Mastering borland delphi2005第十一章。
delphi不能像vc那样在dll中直接导出数据,必须借助第三方媒介吧。
个人理解。不对请指出来。......................
StringTable
begin
1000 ,"test"
1001 ,"BBBB"
1002 ,"CCCC"
1003 ,"DDDD"
end
调用测试
const
fileName='DllRes.dll';procedure TForm1.btnReaderClick(Sender: TObject);
begin
ShowMessage(TResStringHelper.ReadResString(fileName,1000)); === 步骤 1end;procedure TForm1.btnwriterClick(Sender: TObject);
begin
TResStringHelper.UpdateResString(fileName,'Hello',1000); == 步骤 2
end;
用步骤1读出来是test,执行步骤2,读出来还是test? 你自己试试!
{
// dll文件名
CString strFilenameHost = "xx.dll";
// 临时文件名.
CString strFileTemp="Tempfile.dll";
if(strFilenameHost.IsEmpty()) return FALSE; struct _stat ST; FILE* fpread1, *fpwrite; // 获取dll文件长度.
_stat(strFilenameHost, &ST);
int nOldSize = ST.st_size; char mydata[1024] = "hello,china!";
// 计算写入后文件长度.
int nNewSize = nOldSize + 1024; // 打开文件.
if((fpread1=fopen(strFilenameHost,"rb"))==NULL)
return FALSE; if((fpwrite=fopen(strFileTemp,"wb"))==NULL)
return FALSE; // 把文件的读写指针放在文件头.
fseek(fpread1,0,SEEK_SET);
fseek(fpwrite,0,SEEK_SET);
int c; // 把dll文件数据写入到临时文件.
while((c=fgetc(fpread1))!=EOF)
{
fputc(c,fpwrite);
}
// 把要写入的信息保存到临时文件.
fwrite(&mydata,1,1024,fpwrite);
// 关闭文件.
fclose(fpread1);
fclose(fpwrite); CopyFile(strFileTemp,strFilenameHost ,0);
DeleteFile(strFileTemp);
return TRUE;
}
exe在最后加入配置信息的例子很多 希望在这能看到个DLL的
MARK & 收藏