хеш таблицы

Тема в разделе "WASM.RESEARCH", создана пользователем СFF, 10 авг 2010.

  1. СFF

    СFF PP

    Публикаций:
    0
    Регистрация:
    16 янв 2009
    Сообщения:
    233
    Всем привет. Хотел узнать есть ли в ntdll,kernel, ну или в другой библиотека. Функи для работы с хеш таблицами. Пока что пишу свой ми-код с таблицами. Может это лишнее ?
     
  2. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    19841204
    В экспорте ntdll есть RtlComputeCrc32() и RtlHashUnicodeString(). LdrpCalcResourceChecksum() использует MD5Xx(), но последняя группа не экспортируется. ImportTablepHashCanonicalLists() подгружает advapi32 и использует из неё CryptXx(). В ядре подходящих функций нет. Обычно я использую в юзермоде RtlComputeCrc32(), вначале находя её по имени в экспорте, затем при енуме экспорта целевого модуля для каждого имени вычисляется CRC и сравнивается с целевым. В ядре я поступаю иначе, хеш вычисляется свой для каждого имени, например:
    Код (Text):
    1. xLdrCalculateHash:
    2.     %GET_CURRENT_GRAPH_ENTRY
    3. LdrCalculateHash proc uses ebx esi PartialHash:ULONG, StrName:PCHAR, NameLength:ULONG
    4.     mov ecx,NameLength
    5.     mov esi,StrName
    6.     mov ebx,PartialHash
    7.     cld
    8. @@:
    9.     lodsb
    10.     xor ebx,eax
    11.     xor ebx,ecx
    12.     rol ebx,cl
    13.     loop @b
    14.     mov eax,ebx
    15.     ret
    16. LdrCalculateHash endp
     
  3. roman_pro

    roman_pro New Member

    Публикаций:
    0
    Регистрация:
    9 фев 2007
    Сообщения:
    291
  4. СFF

    СFF PP

    Публикаций:
    0
    Регистрация:
    16 янв 2009
    Сообщения:
    233
    Клерк спасибо за црц но я его уже написал сам :) Насчет таблиц хешей, неохота вызывать LoadLibrary лишние вызовы, легче самописную юзать
     
  5. СFF

    СFF PP

    Публикаций:
    0
    Регистрация:
    16 янв 2009
    Сообщения:
    233
    Вообщем сам написал хеш таблицу кому интересно вот.

    Код (Text):
    1. IFNDEF __HASH_TABLE__
    2. __HASH_TABLE equ 1
    3.  
    4. include crc32.asm
    5.  
    6. .code
    7.  
    8. HTABLE_CTX struct
    9.     Count dd ?
    10.     Used  dd ?
    11.     Nodes dd ?
    12.     AllocFunc dd ?
    13.     FreeFunc dd ?
    14.     Crc32 CRC32_CTX <>
    15. HTABLE_CTX ends
    16. PHTABLE_CTX typedef ptr HTABLE_CTX
    17.  
    18. HTABLE_ENTRY struct
    19.     Next PVOID ?
    20.     Key  PVOID ?
    21.     KeySize DWORD ?
    22.     Data DWORD ?
    23. HTABLE_ENTRY ends
    24. PHTABLE_ENTRY typedef ptr HTABLE_ENTRY
    25.  
    26. comment '
    27.     NTSTATUS AllocFunc(DWORD AllocSizeInBytes,PDWORD AllocationAddress)
    28.     NTSTATUS FreeFunc(DWORD AllocationAddress)
    29. '
    30.  
    31. ; pCtx - адресс HTABLE_CTX
    32. ; pInitialSize - начальное количество свободных елементов
    33. ; Return: STATUS_SUCCESS on success, or error status code
    34. htable_create proc uses edi pCtx:PHTABLE_CTX,pInitialSize:DWORD,pAllocFunc:PVOID,pFreeFunc:PVOID
    35. LOCAL Nodes:DWORD
    36.     mov edi,pCtx
    37.     xor eax,eax
    38.     mov ecx,sizeof HTABLE_CTX
    39.     rep stosb
    40.    
    41.     mov edi,pCtx
    42.     assume edi:PHTABLE_CTX 
    43.     cmp pInitialSize,0
    44.     je _exit
    45.    
    46.     mov edx,pAllocFunc
    47.     lea ecx,Nodes
    48.     push ecx
    49.    
    50.     mov ecx,pInitialSize
    51.     mov [edi].Count,ecx
    52.     shl ecx,2 ; BYTE -> DWORD
    53.     push ecx
    54.    
    55.     call dword ptr edx
    56.    
    57.     test eax,eax
    58.     jnz _exit
    59.    
    60.     mov ecx,Nodes
    61.     mov [edi].Nodes,ecx
    62.     mov eax,pAllocFunc
    63.     mov [edi].AllocFunc,eax
    64.     mov eax,pFreeFunc
    65.     mov [edi].FreeFunc,eax
    66.     lea ecx,[edi].Crc32
    67.    
    68.     invoke crc32_init,ecx
    69.    
    70. _exit:
    71.     ret
    72. htable_create endp
    73.  
    74. ;VOID
    75. htable_destroy proc C uses esi edi ebx pCtx:PHTABLE_CTX
    76. LOCAL Item:DWORD
    77. LOCAL Counter:DWORD
    78.  
    79.     mov edx,pCtx
    80.     assume edx:PHTABLE_CTX
    81.     mov ecx,[edx].Count
    82.     test ecx,ecx
    83.     jz _exit
    84.    
    85.     mov esi,[edx].Nodes
    86. _next:
    87.     mov Counter,ecx
    88.     lodsd
    89.    
    90. _list:
    91.     test eax,eax
    92.     jz _empty
    93.    
    94.     assume eax:PHTABLE_ENTRY
    95.     mov ebx,dword ptr [eax].Next
    96.     mov Item,ebx
    97.    
    98.     push eax
    99.     mov ecx,dword ptr [eax].Key
    100.     push ecx
    101.     call [edx].FreeFunc
    102.     mov edx,pCtx
    103.     pop eax
    104.        
    105.     push eax
    106.     call [edx].FreeFunc
    107.     mov edx,pCtx
    108.    
    109.     mov eax,Item
    110.     jmp _list
    111.    
    112. _empty:
    113.     mov ecx,Counter
    114.     loop _next
    115.    
    116.     mov edx,pCtx
    117.     push [edx].Nodes
    118.     call [edx].FreeFunc
    119.        
    120. _exit: 
    121.     ret
    122. htable_destroy endp
    123.  
    124. htable_get_internal proc uses ebx esi edi pCtx:PHTABLE_CTX,pKey:PVOID,pKeySize:DWORD,pAddress:PDWORD
    125. LOCAL pCRC:PCRC32_CTX
    126.  
    127.     mov edx,pCtx
    128.     assume edx:PHTABLE_CTX
    129.     lea ecx,[edx].Crc32
    130.     mov pCRC,ecx
    131.     invoke crc32_final,pCRC
    132.     invoke crc32_update,pCRC,pKey,pKeySize
    133.     mov edx,pCtx
    134.     assume edx:PHTABLE_CTX
    135.     mov ebx,[edx].Count
    136.     mov esi,[edx].Nodes
    137.     xor edx,edx
    138.     div ebx
    139.     shl edx,2
    140.     add esi,edx
    141.    
    142.     lodsd
    143.     test eax,eax
    144.     jz _save
    145.    
    146. _next: 
    147.     mov ecx,pKeySize
    148.     assume eax:PHTABLE_ENTRY
    149.     cmp dword ptr [eax].KeySize,ecx
    150.     jne _noequal
    151.    
    152.     cld
    153.     mov esi,[eax].Key
    154.     mov edi,pKey
    155.     mov ecx,pKeySize
    156.     repe cmpsb
    157.     je _exit
    158.    
    159. _noequal:  
    160.     lea ecx,[eax].Next
    161.     mov edx,pAddress
    162.     mov dword ptr [edx],ecx
    163.    
    164.     mov eax,[eax].Next
    165.  
    166.     test eax,eax
    167.     jnz _next
    168. _exit:
    169.     ret
    170. _save:
    171.     sub esi,4
    172.     mov edx,pAddress
    173.     mov dword ptr [edx],esi
    174.     jmp _exit
    175. htable_get_internal endp
    176.  
    177. htable_get proc uses ebx esi edi pCtx:PHTABLE_CTX,pKey:PVOID,pKeySize:DWORD,pValue:PDWORD
    178. LOCAL pAddress:DWORD
    179.     invoke htable_get_internal,pCtx,pKey,pKeySize,addr pAddress
    180.     test eax,eax
    181.     jz _error
    182.    
    183.     mov ecx,pValue
    184.     assume eax:PHTABLE_ENTRY
    185.     mov edx,[eax].Data
    186.     mov dword ptr [ecx],edx
    187.     xor eax,eax
    188.    
    189. _exit:
    190.     ret
    191. _error:
    192.     mov eax,STATUS_UNSUCCESSFUL
    193.     jmp _exit
    194. htable_get endp
    195.  
    196. htable_add proc uses ebx esi edi pCtx:PHTABLE_CTX,pKey:PVOID,pKeySize:DWORD,pValue:DWORD
    197. LOCAL nKey:DWORD
    198. LOCAL pEntry:PHTABLE_ENTRY
    199. LOCAL pAddress:DWORD
    200.  
    201.     invoke htable_get_internal,pCtx,pKey,pKeySize,addr pAddress
    202.    
    203.     test eax,eax
    204.     jz _notexists
    205.    
    206.     assume eax:PHTABLE_ENTRY
    207.     mov ecx,pValue
    208.     mov dword ptr [eax].Data,ecx
    209.     xor eax,eax
    210.     jmp _exit
    211.    
    212. _notexists:
    213.     mov edx,pCtx
    214.     lea eax,pEntry
    215.     push eax
    216.     push sizeof HTABLE_ENTRY
    217.     call [edx].AllocFunc
    218.     test eax,eax
    219.     jnz _exit
    220.        
    221.     mov edx,pCtx
    222.     lea eax,nKey
    223.     push eax
    224.     push pKeySize
    225.     call [edx].AllocFunc
    226.     test eax,eax
    227.     jnz _free
    228.            
    229.     mov esi,pEntry
    230.     assume esi:PHTABLE_ENTRY
    231.     mov ecx,nKey
    232.     mov dword ptr [esi].Key,ecx
    233.     mov ecx,pKeySize
    234.     mov dword ptr [esi].KeySize,ecx
    235.     mov dword ptr [esi].Next,eax
    236.     mov ecx,pValue
    237.     mov dword ptr [esi].Data,ecx
    238.    
    239.     cld
    240.     mov esi,pKey
    241.     mov edi,nKey
    242.     mov ecx,pKeySize
    243.     rep movsb
    244.    
    245.     ;add to list
    246.     mov eax,pAddress
    247.     mov ecx,pEntry
    248.     mov dword ptr [eax],ecx
    249.    
    250.     mov edx,pCtx
    251.     inc [edx].Used
    252.    
    253.     xor eax,eax
    254.        
    255. _exit:
    256.     ret
    257. _free:
    258.     push eax
    259.     mov edx,pCtx
    260.     push pEntry
    261.     call [edx].FreeFunc
    262.     pop eax
    263.     jmp _exit
    264. htable_add endp
    265.  
    266. ENDIF
    Эт црц
    Код (Text):
    1. IFNDEF __CRC32__
    2. __CRC32__ equ 1
    3.  
    4. CRC32_CTX struct
    5.     Hash    dd ?
    6.     Table   dd 256 dup (?)
    7. CRC32_CTX ends
    8. PCRC32_CTX typedef ptr CRC32_CTX
    9.  
    10. .code
    11.  
    12. crc32_init proc uses esi edi pCtx:PCRC32_CTX
    13.     xor ecx,ecx
    14.     xor edx,edx
    15.     add ecx,256
    16.     cld
    17.     mov edi,pCtx
    18.     lea edi,[edi + CRC32_CTX.Table]
    19.    
    20. _next:
    21.     mov eax,edx
    22.     mov esi,8
    23.    
    24. _inner:
    25.     shr eax,1
    26.     jnc  @f
    27.     xor eax,0EDB88320h
    28.  
    29. @@:
    30.     dec esi
    31.     jnz _inner
    32.    
    33.     stosd
    34.  
    35.     inc edx
    36.     loop _next
    37.    
    38.     mov edi,pCtx
    39.     assume edi:PCRC32_CTX
    40.     xor eax,eax
    41.     mov dword ptr [edi].Hash,eax
    42.    
    43.     ret
    44. crc32_init endp
    45.  
    46. crc32_update proc uses ebx esi edi pCtx:PCRC32_CTX,pBuffer:PVOID,pBufferSize:DWORD
    47.     mov esi,pBuffer
    48.     mov ecx,pBufferSize
    49.     mov edi,pCtx
    50.     assume edi:PCRC32_CTX
    51.     mov edx,[edi].Hash 
    52.     lea edi,[edi + CRC32_CTX.Table]
    53.     not edx
    54.     cld
    55. @@:
    56.     test ecx,ecx
    57.     jz _end
    58.    
    59.     lodsb
    60.     mov ebx,edx
    61.     and ebx,0FFh
    62.     xor bl,al
    63.    
    64.     shr edx,8
    65.     and edx,0FFFFFFh
    66.    
    67.     shl ebx,2 ; byte to dword offset
    68.     xor edx,dword ptr [edi+ebx]
    69.     ;xor edx,0D202EF8Dh
    70.    
    71.     dec ecx
    72.     jmp @B
    73.    
    74. _end:
    75.     not edx
    76.     mov edi,pCtx
    77.     assume edi:PCRC32_CTX
    78.     mov [edi].Hash,edx
    79.     xchg edx,eax
    80.  
    81.     ret
    82. crc32_update endp
    83.  
    84. crc32_final proc pCtx:PCRC32_CTX
    85.     mov ecx,pCtx
    86.     assume ecx:PCRC32_CTX
    87.     mov edx,dword ptr [ecx].Hash
    88.     xor eax,eax
    89.     mov dword ptr [ecx].Hash,eax
    90.     xchg eax,edx
    91.     ret
    92. crc32_final endp
    93.  
    94. crc32 proc pBuffer:PVOID,pBufferSize:DWORD
    95. LOCAL ctx:CRC32_CTX
    96.  
    97.     invoke crc32_init,addr ctx
    98.     invoke crc32_update,addr ctx,pBuffer,pBufferSize
    99.     invoke crc32_final,addr ctx
    100.     ret
    101. crc32 endp
    102.  
    103. ENDIF
    Как юзать пример
    Код (Text):
    1. ;for debug only!!!
    2. MmAlloc proc uses ebx esi edi pAllocSizeInBytes:DWORD,pAllocBuffer:PDWORD
    3.     invoke LocalAlloc,LPTR,pAllocSizeInBytes
    4.     test eax,eax
    5.     jnz _success
    6.    
    7.     mov eax,STATUS_NO_MEMORY
    8.     jmp _exit
    9.    
    10. _success:
    11.     mov edx,pAllocBuffer
    12.     mov dword ptr [edx],eax
    13.     xor eax,eax
    14.    
    15. _exit:
    16.     ret
    17. MmAlloc endp
    18.  
    19. ;for debug only!!!
    20. MmFree proc uses ebx esi edi pMem:DWORD
    21.     invoke LocalFree,pMem
    22.     ret
    23. MmFree endp
    24.  
    25.         invoke htable_create,addr ctx,4,MmAlloc,MmFree
    26.     invoke htable_add,addr ctx,chr$("test1"),5,1
    27.     invoke htable_add,addr ctx,chr$("test2"),5,2
    28.     invoke htable_add,addr ctx,chr$("test3"),5,3
    29.     invoke htable_add,addr ctx,chr$("test4"),5,4
    30.    
    31.     invoke htable_get,addr ctx,chr$("test2"),5,addr temp
    32.    
    33.     invoke htable_destroy,addr ctx
    Как понимаете стиль юза написан попростому. В реале там должен быть ми-код
     
  6. СFF

    СFF PP

    Публикаций:
    0
    Регистрация:
    16 янв 2009
    Сообщения:
    233
  7. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    19841204
    Во первых вы не сказали конкретно задачу/цель использования хешей. Во вторых загрузка и вызов функции из модуля увеличит размер кода не значительно(+5/6 байт на хеш имени апи и пара десятков байт на загрузку модуля). Вдобавок вы во всех своих топиках говорите что пишите мутирующий код, тогда я и не знаю как быть на счёт хотябы этого:
    Код (Text):
    1. lea edi,[edi + CRC32_CTX.Table]
    Какой размер кода, генерирующего эту таблицу, 0xFF*(4 + OpSize), в лучшем случае более килобайта ?
    Вызов:
    Код (Text):
    1.     invoke LocalAlloc,LPTR,pAllocSizeInBytes
    2.     test eax,eax
    3.     jnz _success
    4.    
    5.     mov eax,STATUS_NO_MEMORY
    можно считать кривым, так как вы смешиваете ядерные статусы с пользовательскими функциями, следует не использовать виньапи, либо получать статус и возвращать его.
     
  8. СFF

    СFF PP

    Публикаций:
    0
    Регистрация:
    16 янв 2009
    Сообщения:
    233
    Код (Text):
    1. lea edi,[edi + CRC32_CTX.Table]
    Вы правы я пишу мутирующий код,
    но по идее можно морфнуть эту инстуркцию как add edi,CRC32_CTX.Table. Я вроде правильно понимаю. Так как оффсет полей статичен. Вы же тоже пишете mov eax,dword ptr fs:[TEB.Peb]

    Ну вы правы, но память выделается именно при работе программы. Поэтому сам файл не будет на 0xFF*(4 + OpSize) больше.

    Это понятно, то есть я навязываю статус код свой. Если говорит чесно то при выделении памяти мне вообще по барабану. Какой статус код ошибки будет. Мне важней знать есть память или нет. LocalAlloc->HeapAlloc и согласно доке чтобы получить статус код надо установить атрибут прияма ексептионов иначе никак. Но так как там всего 2 статуса, я решил поставить свой
    Эта офф дока.
     
  9. СFF

    СFF PP

    Публикаций:
    0
    Регистрация:
    16 янв 2009
    Сообщения:
    233
    Я создаю PE builder, тоесть мой зверек должен превращать себя из екзе в длл, и плюс к ютому добавлять експорт и импорт.
    Exe->Dll , там поля всего нужно подправить IMAGE_NT_HEADERS32.OptionalHeader.Characteristics. А вот в свое тело добавить импорт и експорт это уже посложней будет

    С этим я полностью согласен. Просто я и незнал что в ntdll уже есть crc32
     
  10. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    19841204
    Мутирующий код не может содержать данных. Если они есть, то код не мутирующий, а будет пересобран пермутатором на основе описателей данных(фиксапы и прочие дефины).
    Регистр Fs адресует страницу с системным окружением. База сегмента не фиксирована, а адресуется сегментным регистром, в оличае от непосредственных ссылок на данные(0:Offset). Для сегментов с нулевой базой виртуальный адрес равен смещению в сегменте.
    Самое сложное определить фиксапы, которых обычно в екзе нет, но должны быть в длл.
     
  11. СFF

    СFF PP

    Публикаций:
    0
    Регистрация:
    16 янв 2009
    Сообщения:
    233
    Крерк это понятно но там нету данных, там в edi указатель на данные. Причем после мутации. Код сгенерирует данные вновь.
    Так и не понял где там ошибка.

    В висте и семерке уже есть там же ASLR. Я просто хочу создать нулевую длл. Сделать фейковые секции. Запихнуть туда свой ми-код. И добавить импорт и экспорт.
     
  12. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    19841204
    Так для чего вам хеши ?
     
  13. СFF

    СFF PP

    Публикаций:
    0
    Регистрация:
    16 янв 2009
    Сообщения:
    233
    Для быстрой обработки файла. Чтобы не по списку бежать и смотреть адресс експорта, а сразу через хеш таблицу получить. Это быстрее когда, когда всего много. Плюс я еще хотел для knowsdll проверять библиотека лежит там или нет. Вместо каждого вызова функций. Вообщем все для скорости и все

    Да к стате к кому стучать чтобы мне ник можно было сменить? 19841204 задолбал уже
     
  14. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    19841204
    Наоборот медленнее, чем просто имена сравнивать, так как для каждого имени необходимо вычислить хеш.
     
  15. СFF

    СFF PP

    Публикаций:
    0
    Регистрация:
    16 янв 2009
    Сообщения:
    233
    Хлерк посмотри хеш таблицы в wiki там все написано будет
     
  16. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    19841204
    Вам последнее предупреждение.
    По теме: посмотрел вики и не знаю в таком случае что вам нужно и причём тут экспорт.
     
  17. СFF

    СFF PP

    Публикаций:
    0
    Регистрация:
    16 янв 2009
    Сообщения:
    233
    Да клерк не обежайся :) Ладно пробую обьяснить. Меня не интересуют хеш функции md5,md4,..., то есть не обратимое хеширование. Меня интересуют хеш таблици. Доступ к елементу хеш таблици выполняется за короткое время и совсем не важно большая эта таблица или нет. В том и достигается производительность, что найти елементы в 10 GB можно очень быстро. Вот меня и интересует, может ктото это уже реализовал. Но ответов не было поэтому я взял сорсы сфинкса. Есть такой поисковый демон. И перевел его на асму, вот и все. Меня интересует вообще на будущее. Может хеш таблицы уже есть в ком компонентах. Я видел в win7 есть RtlCreateHashTable, в других не видел.
    Я так понял никто их в нашем деле не использует. ну да ладно.
     
  18. 7mm

    7mm New Member

    Публикаций:
    0
    Регистрация:
    15 дек 2009
    Сообщения:
    442
  19. Dr.Golova

    Dr.Golova New Member

    Публикаций:
    0
    Регистрация:
    7 сен 2002
    Сообщения:
    348
    > Мутирующий код не может содержать данных. Если они есть, то код не мутирующий, а будет пересобран пермутатором на основе описателей данных(фиксапы и прочие дефины).

    Щито? :) Доставляет кусок фразы "код не может содержать данных" - таки да, курица обычно не содержит яиц (по крайней мере пока они внутри курицы, они яйцами не называются). Или я гоню?
    Действительно, если код перемешан с данными (шелкодес, или тот же eicar), то пытаться его мутировать это полная жопа.
    Но, код, который использует данные можно прекрасно морфить, если не трогать данные. Как пруф - почти всегда корректная работа виртуализаторов типа ExeCryptor'а или VMProtect'а. Даже на бинарях без релоков. На асмовой мешанине они скорее всего профейлятся, но на HLL по шаблонам прекрасно отличают от кода всякие switch таблицы или блоки try/except/final (развивались долго,да, но факт что таки можно =)

    И это уже на бинарном уровне. Я боюсь заикаца про пермутаторы уровня сорцов - тупейший перловый скрип, превращающий все
    mov eax, offset table
    в
    mov eax, offset table-666
    lea eax, [eax+666]
    выносит мозг той же IDA Pro вместе с хакером и всеми кросрефами
     
  20. Dr.Golova

    Dr.Golova New Member

    Публикаций:
    0
    Регистрация:
    7 сен 2002
    Сообщения:
    348
    > Для быстрой обработки файла. Чтобы не по списку бежать и смотреть адресс експорта

    Имена в таблицае экспорта бинарно отсортированы, так что выигрышь от хэшмапа тут хоть и есть, но сомнителен.

    > В том и достигается производительность, что найти елементы в 10 GB можно очень быстро.

    Практика показала штаа на х86 (и х64 естесно) хэшмап больше 2мб становится весьма неэффективным - постоянно выбивает кэши проца. Так что 10гб я могу допустить только разве что там будут сплошные нули. Для реальных данных - 100к узлов. Дальше лучше использовать таки деревья - если данные поиска статичный то AVL деревья, если динамические - то red-black