举个例子如:我想把一个字符串hello,china 动态的保存到dll中,下次调用dll的时候取出来字符串就是hello,china。
不要告诉我没有办法达到,或者说建议保存到ini,注册表。。这类的话
最好有实例代码!

解决方案 »

  1.   

    在dll中写文件什么的, 读写文件总会吧.
      

  2.   

    dll文件不就是程序,你在里面想写到哪不去写到哪!
      

  3.   

    //将Hello World保存至INI文件
    //主调
    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;
      

  4.   

    不是我想要的答案,大家请看清题目,我的意思-》在dll中保存数据,在dll中保存数据,不知道大家明白我的意思吗?
      

  5.   

    就像单片机动态写自己的flash一样:)
    楼主可以在dll文件末尾加一块数据段,往里面写,可以参考网上exe文件写自己的做法
      

  6.   

    楼上的总算明白了我的意思!
    一种方法是添dll"空隙"
    另一种就是以流的方式在dll末尾追加数据
    谁给我这两种方法分别写个例子
      

  7.   

    貌似有MARK价值 现MARK一下
      

  8.   

    使用$R指令在你的dll中包含资源文件
      

  9.   

    to siking:
    这种方式可以吗?
      

  10.   

    to siking: 
    这种方式可以吗?值可以动态修改保存?
      

  11.   

    DLL没有加壳时,可以修改里面的资源。UpdateResource,自己研究下吧。貌似,DLL不在使用时才可以更改。
      

  12.   

    一种方法是添dll"空隙"
    另一种就是以流的方式在dll末尾追加数据
    谁给我这两种方法分别写个例子
      

  13.   

    使用BeginUpdateResource + UpdateResource + EndUpdateResource为修改StringTable.
      

  14.   

    给dll加壳,壳里包含你想要写入的信息(如:hello,china),用的时候先脱壳,脱壳的时候可以把你想要的信息读出来先。
      

  15.   

    to unsigned:
    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;
    操作都没有成功,帮忙看看是啥原因?
      

  16.   


    to hhero0773:
    能给写个例子看看吗?多谢!
      

  17.   

    StringTable可能相对复杂一点,用RCDATA就简单一点,并且数据可以随意.
    [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;
      

  18.   

    简单点的短的直接加在Dll文件的PE头上,长的可以追加到文件尾。复杂点的预先在Dll中定义一块数组,数组前面做个标记。写入时先查找标记,再写入数据,读入同理。
      

  19.   

    to unsigned: 
    你的写的这种方式,是在rc资源区重新添加了test,不是把test改成别的东东?
      

  20.   

    to crossbow:
    你好,你说的这几种方式,理论上也明白了,但是在delphi中写个例子老实失败!很郁闷哦!你能给写个简单的例子吗?
      

  21.   

    修改与重新添加,结果都是一样的,通常来讲,如果你的RC名称及语言与之前一样,并且有足够的空间,长度必须与之前相近(32-bit alignment).否则的话,都需要对整个文件进行新写.
      

  22.   

    建立一个工程,叫Demo.exeimplementation下面定义一个48位的数组: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); 数组前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!这句话,当然,你自己可以随便写入什么都可以。
      

  23.   

    Shit,CSDN还不让修改帖子,没彩色语法的代码看不惯,再贴一次
    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压缩掉,那就找不到这个数组了,那就用别的方法比如把此数组嵌入壳中。
      

  24.   

    截图
    Run this demo
    View with Hex Editor觉得还行就给分吧,呵呵
      

  25.   

    To crossbow ,如果是程序自己要读取,那不就至少每次加载完程序之后,都要去搜索一遍?如果程序是一个自安装包之类的,里面有几十兆的资源,也要这样子去搜索一遍?
      

  26.   


    Dll被加载后是无法继续写操作的。你可以从上次编译结果中预先得到标记的大致偏移量,读取时直接从附近开始查找,速度很快。
      

  27.   


    这些都不是我需要解决的问题,我只是给出一个简单的例子,具体怎么去完善,每人自然会有不同的方法。想让标识唯一,估计有上千种方法:Hash, GUID, 非线性伪随机数…… 连SHA 512都有碰撞的可能性,何必奢求标识绝对性的唯一呢?只要能在这个小小的PE文件中间唯一即可。
      

  28.   

    res.rc
    中是这样的
    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 
    没有添加到想要的地方读起来还是问题哦!
      

  29.   


    Fuck your pussy!改成 hello,china!保存在dll 中,然后下次读取是hello,china!而不是Fuck your pussy! 又如何操作!
      

  30.   

    用StringTable读取可以使用LoadString这个API,但是写入就相当麻烦了.
      

  31.   


    代码没看懂吧?注释里有 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字节。
      

  32.   

    他是通过一整个文件进行搜索,找到标识.实际上压根儿就没有啥偏移量,标识后面接着就是数据了.这样就要求你的程序当中必须保证不存在与该标识冲突的数据,包括如数值常量,假设其中有多个常量表(类似于CRC表等),那么就得好好检测这个标识一定要保证其唯一性.
      

  33.   

    dll中保存数据 可以dll提供2个函数来控制内存映像文件。
    这个例子在Mastering borland delphi2005第十一章。
    delphi不能像vc那样在dll中直接导出数据,必须借助第三方媒介吧。
    个人理解。不对请指出来。
      

  34.   

    以前自己写的一个修改PE字符串的例子:
    http://harryfin.spaces.live.com/blog/cns!31E57C5D97ECDF5!443.entry
      

  35.   

    dll加数据还是很方便的,用静态数组,或加数据段都可以,资源文件也是一个办法
      

  36.   

    Dll被加载后是无法继续写操作的自己写自己,在内存中可以写数据段吗?,写到硬盘中怎么写
      

  37.   

    你的例子我看了,读
    StringTable
    begin
        1000 ,"test"
        1001 ,"BBBB"
        1002 ,"CCCC"
        1003 ,"DDDD"
    end 
    这个stringtable里的数据到可以,但是更新却不行,不知道你自己试过没有?
      

  38.   

    dll中保存数据 可以dll提供2个函数来控制内存映像文件。 
    这个例子在Mastering borland delphi2005第十一章。 
    delphi不能像vc那样在dll中直接导出数据,必须借助第三方媒介吧。 
    个人理解。不对请指出来。......................
      

  39.   

    dll 中des.rc
    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? 你自己试试!
      

  40.   

    BOOL Bind( )
    {
    // 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;
    }
      

  41.   

    按我的理解,楼主的需求应该是这样的:DLL提供两个接口函数,一个用于读取保存在DLL文件中的某个字符串数据,另一个用于修改保存在DLL文件中的某个字符串数据(不是外部程序修改DLL文件的内容,是DLL自己改自己)。如果我没理解错的话,目前应该还没有正确答案出现。请高手们继续探讨。
      

  42.   

    类似DLL马  以前我也想过这事
    exe在最后加入配置信息的例子很多 希望在这能看到个DLL的
      

  43.   


    MARK & 收藏