Уважаемые форумчане. Помогите решить такую проблему: Есть программа, и у нее может бить к пнимеру 50 копий, и нужно чтоб при первом запуске программа обращалась на сервер в котором есть файл со списком свободных номеров (или последний зарегестрированый номер) после этого программа берет первый свободный номер (последний зарегистрированый и прибавляет к нему 1) и потом из файла удаляет номер который себе взяла(записывает вместо того что был новый. С тем что написано выше проблем нет. Проблема потом сохранить этот номер в программе, так чтоб его было сложно заменить пользователю(в файле не советовать) ЯП: Делфи Зарание спасибо
Сделай пустой ресурс в своей программе, а потом отредактируй его. Ну или еще где-то внутри своего же exe-файла, мест там множество.
Я может, что бы не дать возможность пользователю подменить номер, стоит несколько пересмотреть саму политику проверки? Например привязать MAC-адрес к конкретному номеру копии и при запуске приложения заставлять его связываться с сервером для проверки? Или как вариант, сам номер переделать в абракадабру, формата: XXXX-XXXX-XXXX-XXXX-XXXX-XXXX А нумерацию вести на самом сервере. Пускай попробуюти написать keygen guid, если он не будет генерироваться взависимости от параметров машины, а тупо будет лежать радномно созданый список на сервере.
если уж так надо без файла, то пиши в реестр, что бы сложнее подменить номер на другой - шифруй асимметричным алго и пропускай через CryptProtectData, тогда CryptProtectData - не даст расшифровать (CryptUnprotectData) данные на другом пк\другой учеткой, а асимметричный алго позволит быть более менее уверенным в "истинном" происхождении ключика правда это хрень имхо, лучше уникальный айдишник системы\железа гинерить и проверять ключик на соответствие этому id и прочие условия, тогда и не надо думать как его спрятать
номер это для базы на сервере, там нужно просто чтоб было типа: первая запущенная копия взяла номер 1, вторая 2 ,третяя 3 и т.д. и этот номер в ней и остался GRRRL Power Подскажи пожалуйста или дай исходник как осуществить твою идею, она была б в самый раз.
А, для дельфи не подскажу, потому что не знаю этот ЯП. Насколько знаю, WinAPI не существует для редактирования ресурсов у бинарников, поэтому если только что-то свое городить. Если мегазащита не нужна, можешь тупо вписывать номер в самый конец exe-файла, и его же потом оттуда считывать, файл это не испортит
а если заюзать BeginUpdateResource UpdateResource EndUpdateResource но промежуточный файл по идее все таки создать придется,ну его можно сразу и удалить.
Можно сделать довольно просто, создаешь у себя такую процедуру: Code: procedure Key; asm nop;nop;nop;nop;nop;nop;nop;nop; nop;nop;nop;nop;nop;nop;nop;nop; nop;nop;nop;nop;nop;nop;nop;nop; ...и еще таких строк штук 10 end; Пишешь патч(хоть в самом своем приложении) который ищет эту последовательность байт(не помню код у nop), туда и записываешь любые свои данные. А уже в рантайме можно легко определить адрес той процедуры и прочитать нужные данные, только не вздумай вызывать эту процедуру. Получется без всяких ресурсов.
делать вызов на такую процу нужно обязательно, иначе компилятор просты проигнорирует код и не включит его в бинарник, и не обязательно нопить кстати можно что-нибудь свое записать: Code: procedure bbb(); assembler; asm db $00, $01, 2, 3 // Набор байтов (byte) dw $0001, $0002, 3, 4 // Набор слов (word) dd $00000001, 2, 3 // Набор двойных слов (dword) end; // и где-нибудь делать так, что бы компилятор включил код bbb() в бинарник: ... begin ... Exit; bbb; end;
Можно плз пример или подробней об этом. Можно подробней про это, или пример И про это тоже, или пример
первый способ: Code: procedure keyData(); assembler; asm dd $01020304,$01020304,0,0,0,0 end; procedure path(const exeFile, Key: String); var hFileMap, hFile: THandle; lpMem: Pointer; szFile, i: DWORD; begin hFile:= CreateFileA(PAnsiChar(exeFile), GENERIC_READ or GENERIC_WRITE, FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); if (hFile <> INVALID_HANDLE_VALUE) then try szFile:= GetFileSize(hFile, nil); hFileMap:= CreateFileMappingA(hFile, nil, PAGE_READWRITE , 0, szFile, nil); if (hFileMap <> INVALID_HANDLE_VALUE) then try lpMem:= MapViewOfFile(hFileMap, FILE_MAP_READ or FILE_MAP_WRITE, 0, 0, szFile); if (lpMem <> nil) then try i:= 0; repeat // ищем keyData() по сигнатурке 01 02 03 04 01 02 03 04 if (PDWORD(DWORD(lpMem)+i)^ = $01020304) and (PDWORD(DWORD(lpMem)+i+4)^ = $01020304) then begin // длина ключа не должна превышать размер в keyData(), // который можно определить как sizeof(dword) * число dword в keyData() // пишем ключ Move(Key[1], Pointer(DWORD(lpMem)+i)^, Length(Key)); Break; end; Inc(i); until (szFile <= i); finally UnmapViewOfFile(lpMem); end; finally CloseHandle(hFileMap); end; finally CloseHandle(hFile); end; end; второй отличается немногим, в нем не надо мапить файл, просто открываем его на запись, выставляем указатель на конец файла и пишем ключ. третий способ чуть сложнее, пример где-то тут в разделе выкладывал юзай поиск
bertys не буду писать тебе весь код что бы тупо не скопипастил,а хоть попытался понять. через файлстрим (filesteam далее FS) открываешь на чтение fmopenread файл что надо заменить.получаешь размер типа A:=fs.size; выделяешь память размером А для какого либо указателя (который понадобится в ф-ях что я привел выше)типа: getmem(P,A); читаешь буффер: FS.ReadBuffer(P^,А); потом уже BeginUpdateResource UpdateResource EndUpdateResource описание работы и параметров-в тырнетах. пысы почистить память не забудь