Адресът на машинния код на функцията за повикване се преобразува в друг адрес, когато се преглежда в разглобяване и действително се изпълнява. Защо?

Играех си с пример за shellcode и сложих някакъв код в стека. Ето подходящ фрагмент от него, както се вижда в изгледа на паметта на VS2013:

Memory view:
0x0018FEB4  90 90 90 83 ec 28 eb 0b e8 66 2a 1a 75 50 e8 9d 80 18 75

Сега, когато видя същия код в изгледа за разглобяване, интерпретиран на машинен език x86, всичко върви според очакванията, с изключение на адресите (в малкия край), които виждам за инструкциите за повикване (операционен код E8):

Disassembly view:
0018FEB4  nop  
0018FEB5  nop  
0018FEB6  nop  
0018FEB7  sub         esp,28h  
0018FEBA  jmp         0018FEC7  
0018FEBC  call        75332927  
0018FEC1  push        eax  
0018FEC2  call        75317F64

Ако променя изгледа на разглобяване с кодови байтове, получавам същия тип делта между адреса, който съм записал в паметта, и адреса, който се извиква:

Disassembly view, with code bytes as well:
0018FEBC E8 66 2A 1A 75       call        75332927

Мисля, че може да пропускам някои големи теоретични факти с това, но може ли някой да ми го обясни? Адресите, които исках да извикам, са специфични функционални адреси от kernel32.dll, но трябваше да направя малко аритметика върху тях, за да накарам кода да се изпълни и да извика правилните адреси.


person horiac7    schedule 20.04.2014    source източник
comment
Доста неясно, предполагам, че не осъзнавате, че инструкцията CALL използва относително отместване. 0x18fec1 + 0x75a1a266 == 0x75332927   -  person Hans Passant    schedule 20.04.2014
comment
Благодаря, това беше, не бях взел предвид отместването спрямо следващата инструкция, която използва CALL!   -  person horiac7    schedule 20.04.2014
comment
проверете този въпрос [Адресът на функцията не е действителен кодов адрес][1] [1]: stackoverflow.com/questions/2485336/   -  person Mohammed Abdulmonem    schedule 18.08.2014