DWORD_PTR: undeclared identifier

Тема в разделе "WASM.WIN32", создана пользователем hasuhands1, 25 май 2006.

  1. hasuhands1

    hasuhands1 New Member

    Публикаций:
    0
    Регистрация:
    25 май 2006
    Сообщения:
    6
    Не компилится один простой проект - стелс-программа, невидимая в системе.



    Компилятор (vs6.0) выдает ошибку

    E:\stealth-vs60\main.cpp(59) : error C2065: 'DWORD_PTR' : undeclared identifier





    на строке:

    PIMAGE_NT_HEADERS pNTHeaders = MakePtr(PIMAGE_NT_HEADERS,hmodCaller,pDosHeader->e_lfanew);



    MakePtr это макрос:

    #define MakePtr(cast, base, offset) (cast)((DWORD_PTR)(base) + (DWORD_PTR)(offset))



    В чем может быть проблема. На всякий случай прилагаю исходники:



    [​IMG] _1662504131__xstealth.zip
     
  2. Avoidik

    Avoidik New Member

    Публикаций:
    0
    Регистрация:
    29 дек 2004
    Сообщения:
    288
    Адрес:
    Russia
    Код (Text):
    1.  
    2. typedef ULONG_PTR SIZE_T, *PSIZE_T;
    3. typedef LONG_PTR SSIZE_T, *PSSIZE_T;
    4. typedef ULONG_PTR DWORD_PTR, *PDWORD_PTR;
    5.  




    у меня всё откомпилилось с первого раза :) да и вообще, имхо, можно использовать просто DWORD
     
  3. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    typedef DWORD* DWORD_PTR; тогда уж..
     
  4. hasuhands1

    hasuhands1 New Member

    Публикаций:
    0
    Регистрация:
    25 май 2006
    Сообщения:
    6
    Avoidik



    Т.е. без всяких изменений откомпилилось в vs6.0? Ты можешь мне кинуть список действий, которые ты сделал. Может я туплю?



    typedef ULONG_PTR SIZE_T, *PSIZE_T;

    typedef LONG_PTR SSIZE_T, *PSSIZE_T;

    typedef ULONG_PTR DWORD_PTR, *PDWORD_PTR;

    Но после добавление этих трех строчек возникают другие ошибки:

    E:\stealth-vs60\main.cpp(12) : error C2146: syntax error : missing ';' before identifier 'SIZE_T'

    E:\stealth-vs60\main.cpp(12) : fatal error C1004: unexpected end of file found

    Ругается прямо на пейвый же typedef
     
  5. RedLord

    RedLord Member

    Публикаций:
    0
    Регистрация:
    23 июн 2005
    Сообщения:
    183
    Адрес:
    Ukraine
    hasuhands1

    посмотри в MSSDK файл

    BaseTsd.h
     
  6. Four-F

    Four-F New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2002
    Сообщения:
    1.237
    Код (Text):
    1. #if !defined(_W64)
    2. #if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300
    3. #define _W64 __w64
    4. #else
    5. #define _W64
    6. #endif
    7. #endif
    8.  
    9. #if defined(_WIN64)
    10.     typedef unsigned __int64 ULONG_PTR, *PULONG_PTR;
    11. #else
    12.     typedef _W64 unsigned long ULONG_PTR, *PULONG_PTR;
    13. #endif
    14.  
    15. typedef ULONG_PTR DWORD_PTR, *PDWORD_PTR;




    Если не собираешься компилить для 64-битных машин, но XXX_PTR тебе вообще не нужен. Можешь изменить DWORD_PTR на:

    PCHAR - если приводится указатель на что-то.

    ULONG или DWORD - если приводится смещение, длина и т.п.



    Например, так:
    Код (Text):
    1. #define MakePtr(cast, base, offset) (cast)((PCHAR)(base) + (ULONG)(offset))
     
  7. hasuhands1

    hasuhands1 New Member

    Публикаций:
    0
    Регистрация:
    25 май 2006
    Сообщения:
    6
    Ура, поставил определение типа (спасибо, ребята и особенно Four-F) и теперь main.cpp и replace.cpp компилятся. Но программа сама не собирается, прямо зло берет: почему я такой криворукий :dntknw:



    --------------------Configuration: hz - Win32 Debug--------------------

    Linking...

    LIBCD.lib(crt0.obj) : error LNK2001: unresolved external symbol _main

    Debug/hz.exe : fatal error LNK1120: 1 unresolved externals

    Error executing link.exe.



    hz.exe - 2 error(s), 0 warning(s)



    Читаю MSDN по этому поводу, но пока так ничего и не нашел.

    Может я неправильно проект создаю? Делаю так: создаю новый проект "Win32 application", подключаю к нему файлы и собираю.
     
  8. rmn

    rmn Well-Known Member

    Публикаций:
    0
    Регистрация:
    23 ноя 2004
    Сообщения:
    2.348
    для win32 app точкой входа будет WinMain, а не main:


    Код (Text):
    1. было:
    2.  
    3. int main(int argc, char* argv[])
    4. {
    5. // some code
    6.     return 0;
    7. }
    8.  
    9. надо:
    10.  
    11. int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
    12. {
    13. // some code
    14.      return 0;
    15. }




    ------

    только заметил :) линкер у тебя _main не находит, значит ты создал проект Win32 console application для него соответственно надо не WinMain, а main :)
     
  9. Quantum

    Quantum Паладин дзена

    Публикаций:
    0
    Регистрация:
    6 янв 2003
    Сообщения:
    3.143
    Адрес:
    Ukraine
    Four-F



    char* != long*

    См. определение макроса:
    Код (Text):
    1. (PCHAR)(base) + (ULONG)(offset)


    Компилятор умножает offset на размер указываемого типа, т.е. на единицу (sizeof(char) == 1), а должен умножить на 4! Поэтому DWORD_PTR нужно определить как посоветовал IceStudent.
     
  10. hasuhands1

    hasuhands1 New Member

    Публикаций:
    0
    Регистрация:
    25 май 2006
    Сообщения:
    6
    Если определять как IceStudent, т.е. "typedef DWORD* DWORD_PTR;", то выдает след.ошибку:



    E:\test2\Cpp1.cpp(63) : error C2110: cannot add two pointers



    на строке:

    PIMAGE_NT_HEADERS pNTHeaders = MakePtr(PIMAGE_NT_HEADERS,hmodCaller,pDosHeader->e_lfanew);



    Макрос MakePtr, напомню, состоит из:

    #define MakePtr(cast, base, offset) (cast)((DWORD_PTR)(base) + (DWORD_PTR)(offset))



    В общем, вопрос отктыт. Прога все равно не линкуется, хотя главная функция -- WinMain. Может попробуете у себе собрать - ну ничего не выходит. Уже весь измучился. :dntknw:
     
  11. rmn

    rmn Well-Known Member

    Публикаций:
    0
    Регистрация:
    23 ноя 2004
    Сообщения:
    2.348
    с этими исправлениями скомпилился нормально, только про атрибуты секции .text какой-то warning был:


    Код (Text):
    1. #include <windows.h>
    2. #include <tlhelp32.h>
    3. #include <imagehlp.h>
    4. #include "replace.h"
    5.  
    6. #pragma comment(linker,"/MERGE:.rdata=.text")
    7. #pragma comment(linker,"/SECTION:.text,EWRX")
    8.  
    9. #pragma comment(lib,"imagehlp.lib")
    10. #pragma comment(linker,"/BASE:0x29A00000")
    11.  
    12. typedef DWORD *DWORD_PTR;
    13.  
    14. #define MakePtr(cast, base, offset) (cast)((DWORD_PTR)(base) + (DWORD)(offset))
    15. #define MakeRVAPtr(cast, base, rva) (cast)((DWORD_PTR)(base) + (DWORD)(RVAToOffset((DWORD)base, rva)))
     
  12. Four-F

    Four-F New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2002
    Сообщения:
    1.237
    Quantum, моё утверждение насчет приведения указателей к PCHAR касалось только так называемого случая "pointer arithmetic", когда производятся какие-то математические операции (сложение/вычитание) с указателем и указателем или указателем и смещением/длиной.



    Несколько пракрических примеров.





    1. Макрос CONTAINING_RECORD (есть и SDK и d DDK). Указатель (адрес) приводится к PCHAR.


    Код (Text):
    1. //
    2. // Calculate the address of the base of the structure given its type, and an
    3. // address of a field within the structure.
    4. //
    5.  
    6. #define CONTAINING_RECORD(address, type, field) ((type *)( \
    7.                                                   (PCHAR)(address) - \
    8.                                                   (ULONG_PTR)(&((type *)0)->field)))/code]
    9.  
    10.  
    11.  
    12. 2. DDK, Раздел "Porting Issues Checklist", подраздел "Pointer Arithmetic":
    13.  
    14. Be careful when computing buffer sizes. Consider the following:
    15.  
    16. [code]len = ptr2 − ptr1
    17. /* len could be greater than 2**32 */


    Cast pointers to PCHAR for pointer arithmetic.



    Note If len is declared INT or ULONG, this will generate a compiler warning. Buffer sizes, even when computed correctly, may still exceed the capacity of ULONG.



    Т.е. в данном примере нужно сделать так:


    Код (Text):
    1. ULONG_PTR len;
    2.  
    3. len = (PCHAR) ptr2 - (PCHAR) ptr1;






    3. MSDN: "Beyond Windows XP: Get Ready Now for the Upcoming 64-Bit Version of Windows"



    Finally, for pointer arithmetic, cast pointers to PCHAR instead of ULONG. PCHAR compiles to either 32-bit or 64-bit depending on target bitness, while ULONG is always 32 bits and a cast to ULONG will therefore truncate half of your pointer.


    Код (Text):
    1. ptr = (PVOID)((PCHAR)ptr + pageSize);




    <font color="gray][ hasuhands1</font><!--color--><font color="gray]: В общем, вопрос отктыт. Прога все равно не линкуется, хотя главная функция -- WinMain. ]</font><!--color-->



    Тут масса вариантов. Можно так:


    Код (Text):
    1. #pragma comment(linker,"/ENTRY:main")
    2.  
    3. int APIENTRY main(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
    4. {
    5.     ....
    6.     return 0;
    7. }




    Можно так:


    Код (Text):
    1. #pragma comment(linker,"/ENTRY:main")
    2.  
    3. int main()
    4. {
    5.     ....
    6.     ExitProcess(0);
    7.     return 0;
    8. }




    Можно даже так:


    Код (Text):
    1. #pragma comment(linker,"/ENTRY:main")
    2.  
    3. void main()
    4. {
    5.     ....
    6. }
     
  13. Quantum

    Quantum Паладин дзена

    Публикаций:
    0
    Регистрация:
    6 янв 2003
    Сообщения:
    3.143
    Адрес:
    Ukraine
    Four-F

    Повторяю: указатель на long нельзя приводить к указателю на char, т.к. смещение перед сложением умножается на базовый тип указателя.
    Код (Text):
    1. char* p1 = (char*)0x404000;
    2. p1++; // p1 == 0x40400[b]1[/b]
    3. long* p2 = (long*)0x404000;
    4. p2++; // p2 == 0x40400[b]4[/b]




    Естественно. PCHAR - есть указатель, его размер зависит от платформы. ULONG - есть unsigned long int и по стандарту всегда имеет размер 32 бита. Приводить указатель к стандартному типу фиксированного размера нарушает портабельность. Это всё и так понятно.





    Если ptr2 >= ptr1, никаких проблем не возникнет. Компилятор не может знать заранее, что ptr2 >= ptr1. Поэтому результат лучше всего сразу кастовать на тип len:
    Код (Text):
    1. unsigned long len = (unsigned long)(ptr2 - ptr1);
    2. unsigned int len = (unsigned int)(ptr2 - ptr1);
    3. unsigned short len = (unsigned short)(ptr2 - ptr1);
    4. unsigned char len = (unsigned char)(ptr2 - ptr1);
    5. // ***


    Если я правильно понял, они советуют приводить результат к типу указателя (хоть void*). Но размер буфера никакой не указатель! Так что совет отклоняется.
     
  14. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    Quantum



    Это причина скорее.. Вообще, это и частая ошибка при работе с указателями. Хочешь увеличить его на 1, а он был LPDWORD и получи +=4.



    С другой стороны, часто бывает необходима эта "указательная арифметика" - поэтому и приводят к PCHAR.
     
  15. Four-F

    Four-F New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2002
    Сообщения:
    1.237
    Quantum, хрен с ним ;) Я всё равно точно знаю, что добавлять к указателям смещения/длину нужно так:



    (PVOID) ptr2 = (PVOID)((PCHAR) ptr1 + len);



    И как там ptr1 определён и на что он указывает - по-хрену.



    Вот волшебный макрос - тыщу лет пользуюсь для двиганья указателей:


    Код (Text):
    1. //
    2. //  PVOID
    3. //    AddToPtr (
    4. //      IN PVOID Pointer,
    5. //      IN ULONG Increment
    6. //      );
    7. //
    8.  
    9. #define AddToPtr(p,i) ((PVOID)((PCHAR)(p) + (i)))




    ЗЫ: и вообще мне некогда ;)
     
  16. Quantum

    Quantum Паладин дзена

    Публикаций:
    0
    Регистрация:
    6 янв 2003
    Сообщения:
    3.143
    Адрес:
    Ukraine
    Four-F

    В первом посте ты посоветовал заменить DWORD_PTR на PCHAR. Я обьяснил к чему приведёт такая замена (короче, код не будет работать). Теперь мы говорим о совсем разных вещах.





    У каждого свой стиль программирования, но я думаю, что у этого макроса больше минусов, чем плюсов. Правда, для обфускации сгодится ;) Основной минус в том, что из названия нельзя точно определить что этот макрос делает. Можно подумать, что он учитывает тип указателя и, следовательно, неверно понять смысл кода.
     
  17. hasuhands1

    hasuhands1 New Member

    Публикаций:
    0
    Регистрация:
    25 май 2006
    Сообщения:
    6
    rmn



    слинковалась, жаль, что программа с этими испралениями не работает :dntknw:
     
  18. Four-F

    Four-F New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2002
    Сообщения:
    1.237
    <font color="gray][ Quantum</font><!--color--><font color="gray]: В первом посте ты посоветовал заменить DWORD_PTR на PCHAR. Я обьяснил к чему приведёт такая замена (короче, код не будет работать)... ]</font><!--color-->



    <font color="gray][ Quantum</font><!--color--><font color="gray]: Компилятор умножает offset на размер указываемого типа, т.е. на единицу (sizeof(char) == 1), а должен умножить на 4! ]</font><!--color-->



    Quantum, извини, но при всём моём уважении, ты просто не понимаешь о чём в данном случае идёт речь. Смысл приведения к PCHAR, в данном конкретном случае, как раз в том и состоит, чтобы идиот компилятор не умножал offset на размер указываемого типа. В данном случае мы точно знаем, что мы делаем - смещаем указатель на нужное нам число байт, а компилятор об этом не знает. Наша задача продвинуть указатель на какое-то значение и если мы не првиведём его к PCHAR, то как раз в этом случае код и не будет работать!



    В исходном коде топикстартера макрос MakePtr используется главным образом для перемещения по структурам PE-файла, например, для того, чтобы продвинуть указатель базы модуля к IMAGE_NT_HEADERS. Вот как это делает системная функция RtlImageNtHeader (код упрощён):


    Код (Text):
    1. PIMAGE_NT_HEADERS
    2. RtlImageNtHeader (
    3.     IN [b]PVOID Base[/b]
    4.     )
    5. {
    6.  
    7.     PIMAGE_NT_HEADERS NtHeaders = NULL;
    8.  
    9.     NtHeaders = (PIMAGE_NT_HEADERS)([b](PCHAR)Base[/b] + ((PIMAGE_DOS_HEADER)Base)->e_lfanew);
    10.  
    11.     return NtHeaders;
    12. }


    <font color="gray][ Quantum</font><!--color--><font color="gray]: У каждого свой стиль программирования, но я думаю, что у этого макроса больше минусов, чем плюсов... Основной минус в том, что из названия нельзя точно определить что этот макрос делает. Можно подумать, что он учитывает тип указателя и, следовательно, неверно понять смысл кода. ]</font><!--color-->



    Насчёт стиля - согласен, а вот насчёт имени... IMHO, имя - описательней некуда. Во всяком случае, я, точно знаю, что этот макрос делает ;) И минусов, IMHO, у него вообще нет ;))) Его смысл как раз в том и состоит, чтобы похерить тип указателя и прибавить к нему именно то, что я просил, а не то, что компилятор посчитает правильным!
     
  19. Asterix

    Asterix New Member

    Публикаций:
    0
    Регистрация:
    25 фев 2003
    Сообщения:
    3.576
    Я как-то без макросов обходился, хотя может тоже лишнего

    где нагородил %)
    Код (Text):
    1. int GetPEHeaderInfo(char* lpFileName, PE_HEADER_INFO* lpPEHeaderInfo)
    2. {
    3.     int retValue = 0;
    4.  
    5.     HANDLE hFile = CreateFile(lpFileName, GENERIC_READ,
    6.                               FILE_SHARE_READ, 0, OPEN_EXISTING,
    7.                               FILE_ATTRIBUTE_NORMAL, 0);
    8.     if(hFile != INVALID_HANDLE_VALUE)
    9.     {
    10.         HANDLE hMapFile = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
    11.         if(hMapFile)
    12.         {
    13.             void* lpMapMemory = MapViewOfFile(hMapFile, FILE_MAP_READ, 0, 0, 0);
    14.             if(lpMapMemory)
    15.             {
    16.                 if((*(IMAGE_DOS_HEADER*)lpMapMemory).e_magic == IMAGE_DOS_SIGNATURE)
    17.                 {
    18.                     IMAGE_NT_HEADERS* lpNT_Headers = (IMAGE_NT_HEADERS*)((char*)lpMapMemory +
    19.                                                      (*(IMAGE_DOS_HEADER*)lpMapMemory).e_lfanew);
    20.                     if((*lpNT_Headers).Signature == IMAGE_NT_SIGNATURE)
    21.                     {
    22.                         (*lpPEHeaderInfo).EntryPoint = (*lpNT_Headers).OptionalHeader.AddressOfEntryPoint;
    23.                         (*lpPEHeaderInfo).BaseOfImage = (*lpNT_Headers).OptionalHeader.ImageBase;
    24.                         if(((*lpPEHeaderInfo).EntryPoint != 0) &&
    25.                            ((*lpPEHeaderInfo).BaseOfImage != 0))
    26.                             retValue++;
    27.                     }
    28.                 }
    29.                 UnmapViewOfFile(lpMapMemory);
    30.             }
    31.             CloseHandle(hMapFile);
    32.         }
    33.         CloseHandle(hFile);
    34.     }
    35.     return retValue;
    36. }
    37.  
     
  20. Four-F

    Four-F New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2002
    Сообщения:
    1.237
    Код (Text):
    1. IMAGE_NT_HEADERS* lpNT_Headers = (IMAGE_NT_HEADERS*)([b](char*)[/b]lpMapMemory +
    2.                                  (*(IMAGE_DOS_HEADER*)lpMapMemory).e_lfanew);
    Ну дык у тя тоже самое приведение к PCHAR, точнее у меня тоже самое приведение к char* ;) Ибо



    typedef char CHAR;

    typedef CHAR *PCHAR;