Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 24.12.2013, 15:10   #1
munthrekosh
Пользователь
 
Аватар для munthrekosh
 
Регистрация: 12.11.2011
Сообщений: 80
По умолчанию Занимаюсь переводом кода с Си на Delphi. Вроде перевел, но осталась парочка нюансов

Вот код на Delph:
Код:
function MainF: Integer;
type
  TMStruct = Record
    Start: Integer;
    Stop: Integer;
    Code: Integer;
end;
const
  CAr: array [1..3] of Integer = ($479,$4DF,1);
  WriteEnable: Integer =$1FF;
  INVALID_SET_FILE_POINTER = DWORD(-1);
var
  bl: ^TMStruct;
  ret: Boolean;
  br: DWORD;
  Buf, c: ^byte;
  h: THandle;
  sz, v: Byte;
  bnum, st, size, i, n: Integer;
begin

  h:= CreateFile('test.exe',GENERIC_WRITE or GENERIC_READ, 0, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
  if h=0 Then begin Result:=-1; Exit; end;
  sz:=GetFileSize(h, nil);
  if GetLastError=INVALID_FILE_SIZE Then begin Result:=-2; Exit; end;
  Buf:= nil;
  Buf:= @sz; //Buf=new BYTE[sz]
  if Buf= nil Then begin Result:=-3; Exit; end;
  ret:= ReadFile(h, Buf, sz, br, nil);
  if not(ret) Then begin Result:=-4; Exit; end;
  if br<>sz Then begin Result:=-5; Exit; end;

  {Buf[WriteEnable]=0xC0}
  //c:= nil;
  //c:= Buf+WriteEnable
  //c^:= $C0;

  bnum:= sizeof(CAr) div sizeof(TMStruct);  //int bnum=sizeof(CAr)/sizeof(_block)
  for n:= 0 to bnum do
    begin
      bl:= @CAr[n];
      st:= bl.Start+1;
      size:= bl.Stop -st;

      {Buf[bl->Start]=size}
      //c:= nil;
      //c:= Buf+bl.Start
      //c^:= size;

      {BYTE v=Buf[start+i]}
      //c:= nil;
      //c:= Buf+st
      //c^:= size;
      for i:= 1 to size do
        begin
          inc(c);
          v:= Buf^;
          v:= v xor 255;
          c^:= v;
        end;
    end;

  if SetFilePointer(h, 0, nil, FILE_BEGIN)=INVALID_SET_FILE_POINTER Then begin Result:=-6; Exit; end;
  ret:= WriteFile(h,Buf,sz,br,nil);
  if not(ret) Then begin Result:=-7; Exit; end;
  if br<>sz Then begin Result:=-8; Exit; end;
  CloseHandle(h);
end;

end.
Строки, которые закомментированы с помощью "//", являются нерабочими и я не знаю как реализовать верно данные блоки. А строки между "{}" являются кусками кода из C.
Это в принципе все по этому коду. Но быть может вы найдете еще какие-то ошибки

Для сверки выкладываю код на С:
Код:
#include <windows.h>
  struct _block{
    int Start; // size,data 
    int Stop; // first byte after data
    int Code; // type of coding 1-XOR 0xFF
  } CAr[]={{0x479,0x4DF,1}};

  int WriteEnable=0x1FF; // установка прав на запись в кодовую секцию

  int main(void){
    HANDLE h=CreateFile("test.exe",GENERIC_WRITE | GENERIC_READ, 0, NULL, 
                                  OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    if(h==0) exit(-1);
    int sz=GetFileSize(h,NULL);
    if(sz==INVALID_FILE_SIZE) exit(-2);
    BYTE *Buf=0;
    Buf=new BYTE[sz];
    if(Buf==0) exit(-3);
    DWORD br=0;
    int ret=ReadFile(h,Buf,sz,&br,NULL);
    if(ret==0) exit(-4);
    if(br!=sz) exit(-5);
    Buf[WriteEnable]=0xC0;
    int bnum=sizeof(CAr)/sizeof(_block);
    for(int n=0;n<bnum;n++){
      _block *bl=&CAr[n];
      int start=bl->Start+1;
      int size=bl->Stop - start;
      Buf[bl->Start]=size;
      for(int i=0;i<size;i++){
        BYTE v=Buf[start+i];
        v^=0xFF;
        Buf[start+i]=v;
    }
      }
    ret=SetFilePointer(h,0,0,FILE_BEGIN);
    if(ret==INVALID_SET_FILE_POINTER) exit(-6);
    ret=WriteFile(h,Buf,sz,&br,NULL);
    if(ret==0) exit(-7);
    if(br!=sz) exit(-8);
    CloseHandle(h);
  return 0;
}
Ш.Р.Ю.-программист! йопта!!!

Последний раз редактировалось munthrekosh; 24.12.2013 в 15:11. Причина: поправил заголовок
munthrekosh вне форума Ответить с цитированием
Старый 24.12.2013, 15:48   #2
munthrekosh
Пользователь
 
Аватар для munthrekosh
 
Регистрация: 12.11.2011
Сообщений: 80
По умолчанию

Хм... Попробовал такой вариант

Код:
{Buf[WriteEnable]=0xC0}
c:= nil;
c:= Pointer(DWORD(Buf)+WriteEnable);
c^:= $C0;
 
{Buf[bl->Start]=size}
c:= nil;
c:= Pointer(DWORD(Buf)+bl.Start);
c^:= size;
 
{BYTE v=Buf[start+i]}
c:= nil;
c:= Pointer(DWORD(Buf)+st);
c^:= size;
Компилируется... Но верно ли это?
Ш.Р.Ю.-программист! йопта!!!
munthrekosh вне форума Ответить с цитированием
Старый 24.12.2013, 16:18   #3
Человек_Борща
Старожил
 
Аватар для Человек_Борща
 
Регистрация: 30.12.2009
Сообщений: 11,430
По умолчанию

Если работает одинаково правильно, то код написан верно. Нужно компилировать и тестировать.
Человек_Борща вне форума Ответить с цитированием
Старый 24.12.2013, 16:50   #4
evg_m
Старожил
 
Регистрация: 20.04.2008
Сообщений: 5,527
По умолчанию

Цитата:
, то код написан верно
очевидно нет.
Цитата:
Код:
var
  sz, v: Byte;
  Buf:= @sz; //Buf=new BYTE[sz]}
вместо выделения массива array[0..sz] of byte
простое переназанчение на отдельный байт!!!
в результате непредсказуемые последствия из-за затирания памяти.

Код:
//псевдо С
  buf: PbyteArray;

  buf:=nil;
  GetMem(buff, sz);
  if buf=nil then
Код:
// true Delphi
var
  buff: array of Byte;

  SetLength(buf, sz); 

 ret:= ReadFile(h, @Buf[0], sz, br, nil);
программа — запись алгоритма на языке понятном транслятору

Последний раз редактировалось evg_m; 24.12.2013 в 16:56.
evg_m вне форума Ответить с цитированием
Старый 24.12.2013, 17:41   #5
munthrekosh
Пользователь
 
Аватар для munthrekosh
 
Регистрация: 12.11.2011
Сообщений: 80
По умолчанию

Цитата:
Сообщение от evg_m Посмотреть сообщение
[/CODE]
Код:
// true Delphi
var
  buff: array of Byte;

  SetLength(buf, sz); 

 ret:= ReadFile(h, @Buf[0], sz, br, nil);
Ругается на ret:= ReadFile(h, @Buf[0], sz, br, nil)
Изображения
Тип файла: jpg Снимок.JPG (33.9 Кб, 44 просмотров)
Ш.Р.Ю.-программист! йопта!!!
munthrekosh вне форума Ответить с цитированием
Старый 24.12.2013, 18:44   #6
evg_m
Старожил
 
Регистрация: 20.04.2008
Сообщений: 5,527
По умолчанию

Код:
var pb: Pbyte;

pb:=@buf[0];
ReadFile(n, pb, sz, ...);
программа — запись алгоритма на языке понятном транслятору
evg_m вне форума Ответить с цитированием
Старый 25.12.2013, 06:56   #7
munthrekosh
Пользователь
 
Аватар для munthrekosh
 
Регистрация: 12.11.2011
Сообщений: 80
По умолчанию

Мы тут попытались несколько переработать код для паскаля

Код:
uses
  Windows, SysUtils;
 
type
  _block = record
    Start, Stop, Code: Integer;
  end;
 
const
  CAr: array [0 .. 0] of _block = ((Start: $479; Stop: $4DF; Code: 1));
  WriteEnable: Integer = $1FF;
  INVALID_SET_FILE_POINTER = DWORD(-1);
  INVALID_FILE_SIZE = DWORD($FFFFFFFF);
  
var
  h: THandle;
  Buf: PByteArray;
  br: DWORD;
  ret1: LongBool;
  ret2: Cardinal;
  bnum: Integer;
  n, i: Integer;
  bl: ^_block;
  st, size, sz: Integer;
  v: Byte;
 
begin
  h:= CreateFile('test.exe', GENERIC_WRITE or GENERIC_READ, 0, nil,
                   OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
  if h = 0 then halt(-1);
  sz:= GetFileSize(h, nil);
  if GetLastError = INVALID_FILE_SIZE then halt(-2);
  
  Buf:= nil;
  GetMem(Buf, sz);
  if Buf = nil then halt(-3);
  
  br:= 0;
  ret1:= ReadFile(h, Buf[0], sz, br, nil);
  if ret1 = false then halt(-4);
  if br <> sz then halt(-5);
 
  Buf[Integer(WriteEnable)]:= $C0;
  bnum:= High(CAr) - Low(CAr);
  
  for n := 0 to bnum do
    begin
      bl:= @CAr[n];
      st:= bl.Start + 1;
      size:= bl.Stop - st;
      Buf[bl.Start] := size;
      for i:= 0 to size - 1 do
        begin
          v:= Buf[st + i];
          v:= v xor $FF;
          Buf[st + i]:= v;
        end;
    end;
    
  ret2:= SetFilePointer(h, 0, nil, FILE_BEGIN);
  if ret2 = INVALID_SET_FILE_POINTER then halt(-6);
  ret1:= WriteFile(h, Buf[0], sz, br, nil);
  if ret1 = false then halt(-7);
  if br <> sz then halt(-8);
 
  CloseHandle(h);
  
  halt(0);
end.
И вот такая вот штука... (на картинке) (с первой и второй ошибкой, вроде разобрались, а вот остальные понять не можем)

И я еще немного приналегаю.
Есть вторая часть задания, переводом которой занимается другой человек.
C++:
Код:
#include <stdlib.h>
#include <stdio.h>
 typedef unsigned char BYTE;
 
void Decode(void){
  BYTE *Buf=0;
  __asm{
    mov eax,[ebp+4]
    mov Buf,eax
  }
  BYTE size=Buf[0];
  Buf[0]=0x90;
  for(int i=1;i<=size;i++){ BYTE v=Buf[i]; v^=0xFF; Buf[i]=v; }
}
 
int main(int argc, char* argv[]){
  Decode(); __asm nop;
  if(argc<2){ puts("No Parameter !"); getchar(); return -1;}
  int v=atoi((char *)argv[1]);
  if(v>1998){ puts("Incorrect usage !"); getchar(); return -2;}
  puts("All is Fine !");
  getchar();
return 0;
}
Нам мало чего объясни, просто попросили перевести. И насколько мы поняли, по мере работы, это то что программа шифровальщик должна шифровать часть данного кода (второй части). И во время шифрования происходит запись в кодовую секцию файла, ибо при динамической расшифровке не можем записывать в память.
Второй кусок мы перевели вот так:
Код:
program decipher;
var
  Buf: ^byte;
  size, temp: byte;
  i, v, e: integer;
  vstr: string;
  procedure Decode;
  begin
    Buf:= nil;  { обнуление указателя }
    asm
      MOVL 4(%EBP), %EAX
      MOV %EAX, Buf
    end;
    { Буфер указывает на место возврата, дешифровка, начиная со след. байта }
    size:= Buf^;  { чтобы нормально прочитать size нужна
                   зашифрованная программа }
    { В зашифрованной программе запись в код должна быть разрешена}
    Buf^:= $90; { nop, запись в начало шифрованной области }
    for i:= 1 to size do
    begin
      inc(Buf);
      temp:= Buf^;
      temp:= temp xor 255;
      Buf^:= temp;
    end;
  end;
begin
  if paramcount < 1 then
    begin
      writeln('No parameter !');
      exit;
    end;
  vstr:= paramstr(1);
  Val(vstr, v, e);
  if e <> 0 then
    begin
      writeln('Parameter is not INT !');
      exit;
    end;
  Decode;
  asm nop; end; { Чтобы освободить байт под указание размера шифрованной области }
  if v > 1998 then writeln('Incorrect Usage !') else writeln('All is Fine !');
end.
Мы думаем, что структура CAr в шифровальщике задает секцию шифруемой области из второй части, а именно ту честь где в main идет код осле вызова Decode, ибо при запуске второй части должна производится динамическая дешифровка кода и воспроизводится некоторый код следующий за ней. Так же мы поняли, что на нужно пересчитать все эти секции.
Может кто расскажет как бороться с ошибками и как нам пересчитывать секции записи?
Работаем во FreePascal. Просто так получилось, что человек давший нам это задание, несколько оговорился, а исправился не так давно...

P.S. Наглость, как говорится, второе счастье.
Изображения
Тип файла: jpg 8Vxmw4dJXlU.jpg (46.1 Кб, 36 просмотров)
Ш.Р.Ю.-программист! йопта!!!
munthrekosh вне форума Ответить с цитированием
Старый 25.12.2013, 09:34   #8
evg_m
Старожил
 
Регистрация: 20.04.2008
Сообщений: 5,527
По умолчанию

Процедура в Delphi НЕ ЕСТЬ процедура в С ДАЖЕ если их параметры совпадают. Подробности можно искать по ключевым словам Delphi register, pascal, cdecl, stdcall, and safecall.
Эти особенности как раз и эксплуатируют ассемблерные вставки. Так что результат работы "одинаковых" процедур С и Delphi окажется различен.
программа — запись алгоритма на языке понятном транслятору
evg_m вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Добрый вечер)Я занимаюсь стартапами generalov Помощь студентам 4 14.06.2012 10:10
Проблема с переводом проги на С++ из Delphi Damassk Помощь студентам 0 19.12.2011 12:54
Пару нюансов в масиве Kapitann JavaScript, Ajax 12 04.08.2010 15:55
Помогите пожалуйста с переводом Delphi на C++ Jupiter Помощь студентам 0 07.07.2009 23:33