
рдЕрднрд┐рд╡рд╛рджрди, рд╕рд╛рдерд┐рдпреЛрдВред рдореИрдВрдиреЗ рдЕрднреА рддрдХ рдЦреБрд▓реЗ-рд╕реНрд░реЛрдд-рд╕реНрд░реЛрдд GHIDRA
рдмрд╛рд░реЗ рдореЗрдВ рдирд╣реАрдВ рд╕реБрдирд╛ рд╣реИ, рд╢рд╛рдпрдж рдХреЗрд╡рд▓ рдПрдХ рдмрд╣рд░рд╛ / рдЕрдВрдзрд╛ / рдЧреВрдВрдЧрд╛ / рдХреЛрдИ рдЗрдВрдЯрд░рдиреЗрдЯ рд░рд┐рд╡рд░реНрд╕ рдЗрдВрдЬреАрдирд┐рдпрд░ рдирд╣реАрдВ рд╣реИред рдмреЙрдХреНрд╕ рдХреЗ рдмрд╛рд╣рд░ рдЗрд╕рдХреА рдХреНрд╖рдорддрд╛рдПрдВ рдЕрджреНрднреБрдд рд╣реИрдВ: рд╕рднреА рд╕рдорд░реНрдерд┐рдд рдкреНрд░реЛрд╕реЗрд╕рд░ рдХреЗ рд▓рд┐рдП рдбреАрдХреЙрдореНрдкреЛрд▓рд░, рдирдП рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░ рдХрд╛ рд╕рд░рд▓ рдЬреЛрдбрд╝ (рдЖрдИрдЖрд░ рдореЗрдВ рд╕рдХреНрд╖рдо рд░реВрдкрд╛рдВрддрд░рдг рдХреЗ рдХрд╛рд░рдг рддрддреНрдХрд╛рд▓ рд╕рдХреНрд░рд┐рдп рд╡рд┐рдШрдЯрди рдХреЗ рд╕рд╛рде), рд▓рд┐рдкрд┐рдпреЛрдВ рдХрд╛ рдПрдХ рдЧреБрдЪреНрдЫрд╛ рдЬреЛ рдЬреАрд╡рди рдХреЛ рд╕рд░рд▓ рдмрдирд╛рддрд╛ рд╣реИ, Undo
/ Redo
рдХрд░рдиреЗ рдХреА рд╕рдВрднрд╛рд╡рдирд╛ / рдФрд░ рдпрд╣ рдкреНрд░рджрд╛рди рдХреА рдЧрдИ рд╕рднреА рд╕реБрд╡рд┐рдзрд╛рдУрдВ рдХрд╛ рдХреЗрд╡рд▓ рдПрдХ рдмрд╣реБрдд рдЫреЛрдЯрд╛ рд╣рд┐рд╕реНрд╕рд╛ рд╣реИред рдпрд╣ рдХрд╣рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐ рдореИрдВ рдкреНрд░рднрд╛рд╡рд┐рдд рдерд╛, рд▓рдЧрднрдЧ рдХреБрдЫ рднреА рдирд╣реАрдВ рдХрд╣рдирд╛ рд╣реИред
рдЗрд╕рд▓рд┐рдП, рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ рдореИрдВ рдЖрдкрдХреЛ рдмрддрд╛рдирд╛ рдЪрд╛рд╣реВрдВрдЧрд╛ рдХрд┐ рдореИрдВрдиреЗ GHIDRA
рд▓рд┐рдП рдЕрдкрдирд╛ рдкрд╣рд▓рд╛ рдореЙрдбреНрдпреВрд▓ рдХреИрд╕реЗ рд▓рд┐рдЦрд╛ - Sega Mega Drive / Genesis
рд▓рд┐рдП рдЧреЗрдо рдХреЗ рд▓рд┐рдП рдПрдХ рд░рдо рд▓реЛрдбрд░ред рдЗрд╕реЗ рд▓рд┐рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдореБрдЭреЗ рдЬрд╝рд░реВрд░рдд рдереА ... рдмрд╕ рдХреБрдЫ рдШрдВрдЯреЗ! рдЪрд▓реЛ рдЪрд▓рддреЗ рд╣реИрдВред
рд▓реЗрдХрд┐рди рдЖрдИрдбреАрдП рдХрд╛ рдХреНрдпрд╛?рдореИрдВрдиреЗ IDA
рд▓рд┐рдП рдбрд╛рдЙрдирд▓реЛрдбрд░ рд▓рд┐рдЦрдиреЗ рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЛ рд╕рдордЭрдиреЗ рдореЗрдВ рдХреБрдЫ рджрд┐рди рдмрд┐рддрд╛рдПред рддрдм рдпрд╣ рд╕рдВрд╕реНрдХрд░рдг 6.5
рдерд╛, рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЙрди рджрд┐рдиреЛрдВ рдореЗрдВ рдПрд╕рдбреАрдХреЗ рдкреНрд░рд▓реЗрдЦрди рдХреЗ рд╕рд╛рде рдмрд╣реБрдд рд╕рд╛рд░реА рд╕рдорд╕реНрдпрд╛рдПрдВ рдереАрдВред
рд╣рдо рд╡рд┐рдХрд╛рд╕ рдХрд╛ рдорд╛рд╣реМрд▓ рддреИрдпрд╛рд░ рдХрд░рддреЗ рд╣реИрдВ
GHIDRA
рдбреЗрд╡рд▓рдкрд░реНрд╕ рдиреЗ рд▓рдЧрднрдЧ рд╣рд░ рдЪреАрдЬ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╕реЛрдЪрд╛ ( рдЗрд▓рдлрд╛рдХ , рдЖрдк рдкрд╣рд▓реЗ рдХрд╣рд╛рдВ рдереЗ?)ред рдФрд░, рдирдИ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЛ рдЖрд╕рд╛рди рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рдЙрдиреНрд╣реЛрдВрдиреЗ Eclipse
- GhidraDev
рд▓рд┐рдП рдПрдХ рдкреНрд▓рдЧ-рдЗрди рд╡рд┐рдХрд╕рд┐рдд рдХрд┐рдпрд╛, рдЬреЛ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ "рд░рд╛рдЗрдЯ" рдХреЛрдб рд▓рд┐рдЦрдиреЗ рдореЗрдВ рдорджрдж рдХрд░рддрд╛ рд╣реИ ред рдкреНрд▓рдЧрдЗрди рд╡рд┐рдХрд╛рд╕ рдХреЗ рдорд╛рд╣реМрд▓ рдореЗрдВ рдПрдХреАрдХреГрдд рд╣реИ, рдФрд░ рдЖрдкрдХреЛ рд╕реНрдХреНрд░рд┐рдкреНрдЯ, рд▓реЛрдбрд░, рдкреНрд░реЛрд╕реЗрд╕рд░ рдореЙрдбреНрдпреВрд▓ рдФрд░ рдЙрдирдХреЗ рд▓рд┐рдП рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдХреЗ рд╕рд╛рде-рд╕рд╛рде рдирд┐рд░реНрдпрд╛рдд рдореЙрдбреНрдпреВрд▓ рдмрдирд╛рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ, рд╕рд╛рде рд╣реА рдирд┐рд░реНрдпрд╛рдд рдореЙрдбреНрдпреВрд▓ (рдЬреИрд╕рд╛ рдХрд┐ рдореИрдВ рд╕рдордЭрддрд╛ рд╣реВрдВ, рдпрд╣ рдПрдХ рдкрд░рд┐рдпреЛрдЬрдирд╛ рд╕реЗ рдбреЗрдЯрд╛ рдХрд╛ рдХреБрдЫ рдкреНрд░рдХрд╛рд░ рд╣реИ) рдХреБрдЫ рд╣реА рдХреНрд▓рд┐рдХ рдХреЗ рд╕рд╛рдеред
рдкреНрд▓рдЧрдЗрди рдХреЛ рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, Java
рд▓рд┐рдП Eclipse
рдбрд╛рдЙрдирд▓реЛрдб рдХрд░реЗрдВ, Help
рдХреНрд▓рд┐рдХ рдХрд░реЗрдВ -> Install New Software...
, рдлрд┐рд░ Add
рдмрдЯрди рдкрд░ рдХреНрд▓рд┐рдХ рдХрд░реЗрдВ, рдФрд░ Archive...
рдмрдЯрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдкреНрд▓рдЧрдЗрди рдХреЗ рд╕рд╛рде рд╕рдВрдЧреНрд░рд╣ рдЪрдпрди рд╕рдВрд╡рд╛рдж рдЦреЛрд▓реЗрдВред GhidraDev
рд╕рд╛рде рд╕рдВрдЧреНрд░рд╣ $(GHIDRA)/Extensions/Eclipse/GhidraDev
ред рдЗрд╕реЗ рдЪреБрдиреЗрдВ, Add
рдмрдЯрди рдкрд░ рдХреНрд▓рд┐рдХ рдХрд░реЗрдВред

рджрд┐рдЦрд╛рдИ рджреЗрдиреЗ рд╡рд╛рд▓реА рд╕реВрдЪреА рдореЗрдВ, Ghidra
рдкрд░ рдПрдХ daw Ghidra
, Next >
рдкрд░ рдХреНрд▓рд┐рдХ рдХрд░реЗрдВ Next >
, рд╕рдордЭреМрддреЛрдВ рд╕реЗ рд╕рд╣рдордд рд╣реЛрдВ, Install Anyway
рдХреНрд▓рд┐рдХ Install Anyway
(рдХреНрдпреЛрдВрдХрд┐ рдкреНрд▓рдЧрдЗрди рдХрд╛ рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рдирд╣реАрдВ рд╣реИ), рдФрд░ Eclipse
рдкреБрдирдГ рдЖрд░рдВрдн рдХрд░реЗрдВред

рдХреБрд▓ рдорд┐рд▓рд╛рдХрд░, рдПрдХ рдирдпрд╛ GhidraDev
рдЖрдЗрдЯрдо рдЖрдкрдХреА рдкрд░рд┐рдпреЛрдЬрдирд╛рдУрдВ рдХреЗ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдирд┐рд░реНрдорд╛рдг рдФрд░ рд╡рд┐рддрд░рдг рдХреЗ рд▓рд┐рдП IDE GhidraDev
рдореЗрдВ рджрд┐рдЦрд╛рдИ рджреЗрдЧрд╛ (рдмреЗрд╢рдХ, рдЖрдк рдирдП Eclipse
рдкрд░рд┐рдпреЛрдЬрдирд╛рдУрдВ рдХреЗ рд▓рд┐рдП рд╕рд╛рдорд╛рдиреНрдп рд╡рд┐рдЬрд╝рд╛рд░реНрдб рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рднреА рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ)ред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рд╡рд┐рдХрд╕рд┐рдд рдкреНрд▓рдЧ-рдЗрди рдпрд╛ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЛ рдбреАрдмрдЧ рдХрд░рдиреЗ рдХрд╛ рдЕрд╡рд╕рд░ рд╣реИред

рдФрд░ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдбрд┐рдмрдЧрд░ рдХрд╣рд╛рдВ рд╣реИ?рдХреНрдпрд╛ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ GHIDRA
рд╕рд╛рде рд╕реНрдерд┐рддрд┐ рдХреЛ GHIDRA
рд╣реИ рдХрдордмрдЦреНрдд рдХрд░реНрдХрд╢ рдкреНрд░рдЪрд╛рд░ рд▓реЗрдЦ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рд▓рдЧрднрдЧ рдПрдХ рд╣реА рд╕рд╛рдордЧреНрд░реА рд╣реЛрддреА рд╣реИ, рдЬреЛ, рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╕рдЪ рдирд╣реАрдВ рд╣реИред рдПрдХ рдЙрджрд╛рд╣рд░рдг? рд╣рд╛рдБ, рдХреГрдкрдпрд╛:
рдЙрдкрдХрд░рдг рдХрд╛ рд╡рд░реНрддрдорд╛рди рд╕рдВрд╕реНрдХрд░рдг 9.0 рд╣реИред рдФрд░ рдЯреВрд▓ рдореЗрдВ рдХреНрд░рд┐рдкреНрдЯреИрдирд╛рд▓рд┐рд╕рд┐рд╕ рдЬреИрд╕реЗ рдЕрддрд┐рд░рд┐рдХреНрдд рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХреЛ рд╢рд╛рдорд┐рд▓ рдХрд░рдиреЗ рдХреЗ рд╡рд┐рдХрд▓реНрдк рд╣реИрдВ, рдУрд▓реАрдбрдмрдЧ рдХреЗ рд╕рд╛рде рдмрд╛рддрдЪреАрдд, рдШрд┐рджреНрд░рд╛ рдбреАрдмрдЧрд░ред
рдФрд░ рдпрд╣ рд╕рдм рдХрд╣рд╛рдБ рд╣реИ? рдирд╣реАрдВ!
рджреВрд╕рд░рд╛ рдмрд┐рдВрджреБ: рдЦреБрд▓рд╛рдкрдиред рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдпрд╣ рд▓рдЧрднрдЧ рд╡рд╣рд╛рдБ рд╣реИ, рд▓реЗрдХрд┐рди рд▓рдЧрднрдЧ рдХреЛрдИ рднреА рдирд╣реАрдВ рд╣реИред GHIDRA
рдореЗрдВ Java
рдореЗрдВ рд▓рд┐рдЦреЗ рдЧрдП рдШрдЯрдХреЛрдВ рдХреЗ рд╕реНрд░реЛрдд рд╕реНрд░реЛрдд рд╣реЛрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдпрджрд┐ рдЖрдк Gradle
рд▓рд┐рдкрд┐рдпреЛрдВ рдХреЛ рджреЗрдЦрддреЗ рд╣реИрдВ, рддреЛ рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдЧреБрдкреНрдд рд╕реЗ рдмрд╛рд╣рд░реА рдкрд░рд┐рдпреЛрдЬрдирд╛рдУрдВ рдХреЗ рдПрдХ рд╕рдореВрд╣ рдкрд░ рдирд┐рд░реНрднрд░рддрд╛рдПрдВ рд╣реИрдВ рдкреНрд░рдпреЛрдЧрд╢рд╛рд▓рд╛ NSA
рд░рд┐рдкреЙрдЬрд┐рдЯрд░реАред
рд▓реЗрдЦрди рдХреЗ рд╕рдордп, рдХреЛрдИ рдбрд┐рдХрдВрдкрд╛рдЗрд▓рд░ рдФрд░ SLEIGH
(рдпрд╣ рдЖрдИрдЖрд░ рдХреЗ рд▓рд┐рдП рдкреНрд░реЛрд╕реЗрд╕рд░ рдореЙрдбреНрдпреВрд▓ рдФрд░ рд░реВрдкрд╛рдВрддрд░рдг рдХреЗ рд╡рд┐рд╡рд░рдгреЛрдВ рдХреЛ рд╕рдВрдХрд▓рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЙрдкрдпреЛрдЧрд┐рддрд╛ рд╣реИ)ред
рдЦреИрд░ рдУрд╣ рдареАрдХ рд╣реИ, рдореИрдВ рдХреБрдЫ рд╕реЗ рд╡рд┐рдЪрд▓рд┐рдд рд╣реВрдБред
рддреЛ, рдЖрдЗрдП Eclipse
рдореЗрдВ рдПрдХ рдирдИ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдмрдирд╛рдПрдВред
рд▓реЛрдбрд░ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдмрдирд╛рдПрдВ
GhidraDev
-> New
-> Ghidra Module Project...
рд╣рдо рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреЗ рдирд╛рдо рдХреЛ рдЗрдВрдЧрд┐рдд рдХрд░рддреЗ рд╣реИрдВ (рд╣рдо рдЗрд╕ рдмрд╛рдд рдХрд╛ рдзреНрдпрд╛рди рд░рдЦрддреЗ рд╣реИрдВ рдХрд┐ Loader
рдкреНрд░рдХрд╛рд░ рдХреЗ рд╢рдмреНрджреЛрдВ рдХреЛ рдлрд╝рд╛рдЗрд▓ рдирд╛рдореЛрдВ рд╕реЗ рдЪрд┐рдкрдХрд╛рдпрд╛ рдЬрд╛рдПрдЧрд╛, рдФрд░ рдХреНрд░рдо рдореЗрдВ sega_loaderLoader.java
рдЬреИрд╕реА рдХреБрдЫ рднреА рдкреНрд░рд╛рдкреНрдд рдирд╣реАрдВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдЙрдиреНрд╣реЗрдВ рддрджрдиреБрд╕рд╛рд░ рдирд╛рдо рджреЗрддреЗ рд╣реИрдВ)ред

Next >
рдХреНрд▓рд┐рдХ рдХрд░реЗрдВред рдпрд╣рд╛рдВ рд╣рдо рдЙрди рд╢реНрд░реЗрдгрд┐рдпреЛрдВ рдХреЗ рд╕рд╛рдордиреЗ рдбреМрд╕ рд░рдЦрддреЗ рд╣реИрдВ рдЬрд┐рдирдХреА рд╣рдореЗрдВ рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред рдореЗрд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рдпрд╣ рдХреЗрд╡рд▓ рдПрдХ Loader
ред Next >
рдХреНрд▓рд┐рдХ рдХрд░реЗрдВред

рдпрд╣рд╛рдВ рд╣рдо
рд╕рд╛рде рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдХреЗ рд▓рд┐рдП рдкрде рдХреЛ рдЗрдВрдЧрд┐рдд рдХрд░рддреЗ рд╣реИрдВред Next >
рдХреНрд▓рд┐рдХ рдХрд░реЗрдВред

GHIDRA
рдкрд╛рдЗрдерди ( GHIDRA
рдорд╛рдзреНрдпрдо рд╕реЗ) рдореЗрдВ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рд▓рд┐рдЦрдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред рдореИрдВ Java
рдореЗрдВ рд▓рд┐рдЦреВрдВрдЧрд╛, рдЗрд╕рд▓рд┐рдП рдореИрдВ рдПрдХ рджрд╛рд╡ рдирд╣реАрдВ рд▓рдЧрд╛рддрд╛ рд╣реВрдВред рдореИрдВ Finish
рджрдмрд╛рддрд╛ рд╣реВрдВред

рдПрдХ рдХреЛрдб рд▓рд┐рдЦрдирд╛
рдЦрд╛рд▓реА рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдЯреНрд░реА рдкреНрд░рднрд╛рд╡рд╢рд╛рд▓реА рд▓рдЧрддрд╛ рд╣реИ:

java
рдХреЛрдб рд╡рд╛рд▓реА рд╕рднреА рдлрд╛рдЗрд▓реЗрдВ /src/main/java
рд╢рд╛рдЦрд╛ рдореЗрдВ рд╣реИрдВ:

getName ()
рдЖрд░рдВрдн рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЪрд▓рд┐рдП рдмреВрдЯрд▓реЛрдбрд░ рдХреЗ рд▓рд┐рдП рдПрдХ рдирд╛рдо рдЪреБрдиреЗрдВред getName()
рд╡рд┐рдзрд┐ рдЗрд╕реЗ рд▓реМрдЯрд╛рддреА рд╣реИ:
@Override public String getName() { return "Sega Mega Drive / Genesis Loader"; }
findSupportedLoadSpecs ()
findSupportedLoadSpecs()
рд╡рд┐рдзрд┐ рддрдп рдХрд░рддреА рд╣реИ (рдмрд╛рдЗрдирд░реА рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдирд┐рд╣рд┐рдд рдбреЗрдЯрд╛ рдХреЗ рдЖрдзрд╛рд░ рдкрд░) рдЬреЛ рдкреНрд░реЛрд╕реЗрд╕рд░ рдореЙрдбреНрдпреВрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ findSupportedLoadSpecs()
рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП (рд╕рд╛рде рд╣реА IDA
)ред GHIDRA
рд╢рдмреНрджрд╛рд╡рд▓реА рдореЗрдВ GHIDRA
рдЗрд╕реЗ Compiler Language
рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред рдЗрд╕рдореЗрдВ рд╢рд╛рдорд┐рд▓ рд╣реИрдВ: рдкреНрд░реЛрд╕реЗрд╕рд░, рдПрдВрдбрд┐рдпрдирдиреЗрд╕, рдмрд┐рдЯрдиреЗрд╕ рдФрд░ рдХрдВрдкрд╛рдЗрд▓рд░ (рдпрджрд┐ рдЬреНрдЮрд╛рдд рд╣реЛ)ред
рдпрд╣ рд╡рд┐рдзрд┐ рд╕рдорд░реНрдерд┐рдд рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░ рдФрд░ рднрд╛рд╖рд╛рдУрдВ рдХреА рд╕реВрдЪреА рд▓реМрдЯрд╛рддреА рд╣реИред рдпрджрд┐ рдбреЗрдЯрд╛ рдЧрд▓рдд рдкреНрд░рд╛рд░реВрдк рдореЗрдВ рд╣реИ, рддреЛ рд╣рдо рдмрд╕ рдПрдХ рдЦрд╛рд▓реА рд╕реВрдЪреА рд▓реМрдЯрд╛рддреЗ рд╣реИрдВред
рддреЛ, Sega Mega Drive
рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рд╢рдмреНрдж " SEGA
" рд╕рдмрд╕реЗ рдЕрдзрд┐рдХ рдмрд╛рд░ рд╣реЗрдбрд░ рдХреЗ рдСрдлрд╕реЗрдЯ 0x100
рдкрд░ рдореМрдЬреВрдж рд╣реЛрддрд╛ рд╣реИ (рдпрд╣ рдПрдХ рд╢рд░реНрдд рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди 99% рдорд╛рдорд▓реЛрдВ рдореЗрдВ рдкреВрд░рд╛ рд╣реЛрддрд╛ рд╣реИ)ред рдЖрдкрдХреЛ рдпрд╣ рдЬрд╛рдВрдЪрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдХрд┐ рдХреНрдпрд╛ рдпрд╣ рд▓рд╛рдЗрди рдЖрдпрд╛рддрд┐рдд рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рд╣реИред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, ByteProvider provider
рдХреЛ findSupportedLoadSpecs()
ByteProvider provider
, рдЬрд┐рд╕рдХреЗ рд╕рд╛рде рд╣рдо рдлрд╝рд╛рдЗрд▓ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░реЗрдВрдЧреЗред
рдХрд┐рд╕реА рдлрд╝рд╛рдЗрд▓ рд╕реЗ рдбреЗрдЯрд╛ рдкрдврд╝рдиреЗ рдХреА рд╕реБрд╡рд┐рдзрд╛ рдХреЗ рд▓рд┐рдП рд╣рдо рдПрдХ BinaryReader
рдСрдмреНрдЬреЗрдХреНрдЯ рдмрдирд╛рддреЗ рд╣реИрдВ:
BinaryReader reader = new BinaryReader(provider, false);
рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ false
рддрд░реНрдХ Big Endian
рдХрд╛ рдЙрдкрдпреЛрдЧ рдкрдврд╝рддреЗ рд╕рдордп рдЗрдВрдЧрд┐рдд рдХрд░рддрд╛ рд╣реИред рдЕрдм рд░реЗрдЦрд╛ рдкрдврд╝рддреЗ рд╣реИрдВред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, reader
рдСрдмреНрдЬреЗрдХреНрдЯ рдХреА readAsciiString(offset, size)
рд╡рд┐рдзрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ:
reader.readAsciiString(0x100, 4).equals(new String("SEGA"))
рдпрджрд┐ equals()
true
, рддреЛ рд╣рдо Segov рд░рдо рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░ рд░рд╣реЗ рд╣реИрдВ, рдФрд░ рд╕реВрдЪреА рдореЗрдВ List<LoadSpec> loadSpecs = new ArrayList<>();
рдореЛрдЯреЛрд░реЛрд▓рд╛ m68k
рдЬреЛрдбрд╝рдирд╛ рд╕рдВрднрд╡ рд╣реЛрдЧрд╛ред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдкреНрд░рдХрд╛рд░ рдХреА рдПрдХ рдирдИ рдСрдмреНрдЬреЗрдХреНрдЯ рдмрдирд╛рдПрдВ LoadSpec
, рдЬрд┐рд╕рдХрд╛ рдирд┐рд░реНрдорд╛рддрд╛ рд▓реЛрдбрд░ рдСрдмреНрдЬреЗрдХреНрдЯ (рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, this
) рдХреЛ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рддрд╛ рд╣реИ, рдПрдХ ImageBase
рдЬрд┐рд╕рдореЗрдВ ROM рд▓реЛрдб рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛, рдкреНрд░рдХрд╛рд░ рдХрд╛ рдПрдХ рдСрдмреНрдЬреЗрдХреНрдЯ LanguageCompilerSpecPair
рдФрд░ рдПрдХ рдЭрдВрдбрд╛ - рдХреНрдпрд╛ рдпрд╣ LoadSpec
рд╕реВрдЪреА рдореЗрдВ рджреВрд╕рд░реЛрдВ рдХреЗ рдмреАрдЪ LoadSpec
рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ (рд╣рд╛рдВ, рд╕реВрдЪреА рдореЗрдВ рд╣рд╛рдВ) рдПрдХ рд╕реЗ рдЕрдзрд┐рдХ LoadSpec
рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ)ред
LanguageCompilerSpecPair
рд▓рд┐рдП рдирд┐рд░реНрдорд╛рддрд╛ рдкреНрд░рд╛рд░реВрдк рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рд╣реИ:
- рдкрд╣рд▓рд╛ рддрд░реНрдХ
languageID
, " ProcessorName: Endianness: рдмрд┐рдЯреНрд╕: ExactCpu " рд░реВрдк рдХреА рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧред рдореЗрд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рдпрд╣ " 68000: BE: 32: MC68020 " рд▓рд╛рдЗрди рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП (рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ, рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ MC68000
рдбрд┐рд▓реАрд╡рд░реА рдореЗрдВ рд╢рд╛рдорд┐рд▓ рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рдРрд╕реА рд╕рдорд╕реНрдпрд╛ рдирд╣реАрдВ рд╣реИ)ред ExactCpu
default
рд╣реЛ рд╕рдХрддрд╛ default
- рджреВрд╕рд░рд╛ рддрд░реНрдХ,
compilerSpecID
, рдЬрд┐рд╕реЗ рдЖрдкрдХреЛ рдпрд╣рд╛рдВ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдХреЛ рдЦреЛрдЬрдиреЗ рдХреЗ рд▓рд┐рдП рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдореЗрдВ
рдкреНрд░реЛрд╕реЗрд╕рд░ рд╡рд┐рд╡рд░рдг ( $(GHIDRA)/Ghidra/Processors/68000/data/languages
) рдХреЗ рд╕рд╛рде 68000.opinion
рдлрд╝рд╛рдЗрд▓ рдореЗрдВ 68000.opinion
ред рд╣рдо рджреЗрдЦрддреЗ рд╣реИрдВ рдХрд┐ рдХреЗрд╡рд▓ default
рдпрд╣рд╛рдБ рдЗрдВрдЧрд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рджрд░рдЕрд╕рд▓, рд╣рдо рдЗрд╕рдХрд╛ рд╕рдВрдХреЗрдд рджреЗрддреЗ рд╣реИрдВ
рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреЛрдб рд╣реИрдВ (рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рдЕрдм рддрдХ рдХреБрдЫ рднреА рдЬрдЯрд┐рд▓ рдирд╣реАрдВ рд╣реИ):
@Override public Collection<LoadSpec> findSupportedLoadSpecs(ByteProvider provider) throws IOException { List<LoadSpec> loadSpecs = new ArrayList<>(); BinaryReader reader = new BinaryReader(provider, false); if (reader.readAsciiString(0x100, 4).equals(new String("SEGA"))) { loadSpecs.add(new LoadSpec(this, 0, new LanguageCompilerSpecPair("68000:BE:32:MC68020", "default"), true)); } return loadSpecs; }
рдореЙрдбреНрдпреВрд▓ рдХреЗ рд╕рдВрджрд░реНрдн рдореЗрдВ рдЖрдИрдбреАрдП рдФрд░ GHIDRA рдХреЗ рдмреАрдЪ рдХрд╛ рдЕрдВрддрд░рдПрдХ рдЕрдВрддрд░ рд╣реИ, рдФрд░ рдпрд╣ рдЕрднреА рднреА рдмрд╣реБрдд рдордЬрдмреВрдд рд╣реИред GHIDRA
рдЖрдк рдПрдХ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рд▓рд┐рдЦ рд╕рдХрддреЗ рд╣реИрдВ рдЬреЛ рд╡рд┐рднрд┐рдиреНрди рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░, рдЕрд▓рдЧ-рдЕрд▓рдЧ рдбреЗрдЯрд╛ рд╕реНрд╡рд░реВрдкреЛрдВ рдХреЛ рд╕рдордЭреЗрдЧрд╛, рдПрдХ рд▓реЛрдбрд░, рдПрдХ рдкреНрд░реЛрд╕реЗрд╕рд░ рдореЙрдбреНрдпреВрд▓, рдбрд┐рдХрдореНрдкрд╛рдЗрд▓рд░ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдФрд░ рдЕрдиреНрдп рдЕрдЪреНрдЫрд╛рдИрдпрд╛рдВ рд╣реЛрдЧреАред
IDA
, рдпрд╣ рдкреНрд░рддреНрдпреЗрдХ рдкреНрд░рдХрд╛рд░ рдХреЗ рдРрдб-рдСрди рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрд▓рдЧ рдкрд░рд┐рдпреЛрдЬрдирд╛ рд╣реИред
рдХрд┐рддрдирд╛ рдЕрдзрд┐рдХ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ? рдореЗрд░реА рд░рд╛рдп рдореЗрдВ, GHIDRA
- рдХрдИ рдмрд╛рд░!
рд▓реЛрдб ()
рдЗрд╕ рдкрджреНрдзрддрд┐ рдореЗрдВ, рд╣рдо рд╕реЗрдЧрдореЗрдВрдЯ рдмрдирд╛рдПрдВрдЧреЗ, рдЗрдирдкреБрдЯ рдбреЗрдЯрд╛ рдкреНрд░реЛрд╕реЗрд╕ рдХрд░реЗрдВрдЧреЗ, рдХреЛрдб рдФрд░ рдкрд╣рд▓реЗ рд╕реЗ рдЬреНрдЮрд╛рдд рд▓реЗрдмрд▓ рдмрдирд╛рдПрдВрдЧреЗред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╡рд╕реНрддреБрдУрдВ рдХреЛ рдкреНрд░рд╡реЗрд╢ рджреНрд╡рд╛рд░ рдкрд░ рд╣рдорд╛рд░реА рдорджрдж рдХреЗ рд▓рд┐рдП рдкреНрд░рд╕реНрддреБрдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ:
ByteProvider provider
: рд╣рдо рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЙрд╕реЗ рдЬрд╛рдирддреЗ рд╣реИрдВред рдмрд╛рдЗрдирд░реА рдлрд╝рд╛рдЗрд▓ рдбреЗрдЯрд╛ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдирд╛LoadSpec loadSpec
: рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░ рдХрд╛ рд╡рд┐рдирд┐рд░реНрджреЗрд╢ LoadSpec loadSpec
рдХреЗ рдЖрдпрд╛рдд рдЪрд░рдг рдХреЗ рджреМрд░рд╛рди findSupportedLoadSpecs
рдЧрдпрд╛ рд╣реИ findSupportedLoadSpecs
рд╡рд┐рдзрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЧрдпрд╛ findSupportedLoadSpecs
ред рдпрд╣ рдЖрд╡рд╢реНрдпрдХ рд╣реИ рдпрджрд┐, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╣рдо рдПрдХ рдореЙрдбреНрдпреВрд▓ рдореЗрдВ рдХрдИ рдбреЗрдЯрд╛ рдкреНрд░рд╛рд░реВрдкреЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реИрдВред рдЖрд░рд╛рдо рд╕реЗList<Option> options
: List<Option> options
рд╕реВрдЪреА (рдХрд╕реНрдЯрдо рд╕рд╣рд┐рдд)ред рдореИрдВрдиреЗ рдЕрднреА рддрдХ рдЙрдирдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдирд╛ рдирд╣реАрдВ рд╕реАрдЦрд╛ рд╣реИProgram program
: рдореБрдЦреНрдп рд╡рд╕реНрддреБ рдЬреЛ рд╕рднреА рдЖрд╡рд╢реНрдпрдХ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рддрдХ рдкрд╣реБрдВрдЪ рдкреНрд░рджрд╛рди рдХрд░рддреА рд╣реИ: рд▓рд┐рд╕реНрдЯрд┐рдВрдЧ, рдкрддрд╛ рд╕реНрдерд╛рди, рдЦрдВрдб, рд▓реЗрдмрд▓, рд╕рд░рдгрд┐рдпрд╛рдВ рдмрдирд╛рдирд╛, рдЖрджрд┐редMemoryConflictHandler handler
рдФрд░ TaskMonitor monitor
: рд╣рдореЗрдВ рд╢рд╛рдпрдж рд╣реА рдХрднреА рдЙрдирдХреЗ рд╕рд╛рде рд╕реАрдзреЗ рдХрд╛рдо рдХрд░рдирд╛ рдкрдбрд╝рддрд╛ рд╣реИ (рдЖрдорддреМрд░ рдкрд░, рдЗрди рд╡рд╕реНрддреБрдУрдВ рдХреЛ рддреИрдпрд╛рд░ рддрд░реАрдХреЛрдВ рд╕реЗ рдЧреБрдЬрд░рдирд╛)MessageLog log
: рд▓рдХрдбрд╝рд╣рд╛рд░рд╛
рддреЛ, рд╢реБрд░реБрдЖрдд рдХреЗ рд▓рд┐рдП, рдЖрдЗрдП рдХреБрдЫ рдСрдмреНрдЬреЗрдХреНрдЯ рдмрдирд╛рдПрдВ рдЬреЛ GHIDRA
рд╕рдВрд╕реНрдерд╛рдУрдВ рдФрд░ рдореМрдЬреВрджрд╛ рдбреЗрдЯрд╛ рдХреЗ рд╕рд╛рде рд╣рдорд╛рд░реЗ рдХрд╛рдо рдХреЛ рд╕рд░рд▓ GHIDRA
ред рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ, рд╣рдореЗрдВ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ BinaryReader
рдЖрд╡рд╢реНрдпрдХрддрд╛ BinaryReader
:
BinaryReader reader = new BinaryReader(provider, false);
рдЕрдЧрд▓рд╛ред рдпрд╣ рд╣рдорд╛рд░реЗ рд▓рд┐рдП рдмрд╣реБрдд рдЙрдкрдпреЛрдЧреА рд╣реЛрдЧрд╛ рдФрд░ FlatProgramAPI
рд╡рд░реНрдЧ рдХреЗ рд▓рдЧрднрдЧ рдкреВрд░реЗ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЛ рд╕рд░рд▓ рдХрд░реЗрдЧрд╛ (рдЖрдк рдмрд╛рдж рдореЗрдВ рджреЗрдЦреЗрдВрдЧреЗ рдХрд┐ рдЖрдк рдЗрд╕рдХреЗ рд╕рд╛рде рдХреНрдпрд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ):
FlatProgramAPI fpa = new FlatProgramAPI(program, monitor);
рд░рдо рд╣реЗрдбрд┐рдВрдЧ
рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдпрд╣ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░реЗрдВрдЧреЗ рдХрд┐ рдПрдХ рд╕рд╛рдорд╛рдиреНрдп рд╕реЗрдЧрд╛ рд░рдо рдХреА рд╣реЗрдбрд┐рдВрдЧ рдХреНрдпрд╛ рд╣реИред рдкрд╣рд▓реЗ 0x100
рдмрд╛рдЗрдЯреНрд╕ рдореЗрдВ рд╡реИрдХреНрдЯрд░реЛрдВ рдХреЗ рд▓рд┐рдП 64 DivideByZero
рдкреЙрдЗрдВрдЯрд░реНрд╕ рдХреА рдПрдХ рддрд╛рд▓рд┐рдХрд╛ рд╣реЛрддреА рд╣реИ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП: Reset
, Trap
, DivideByZero
, VBLANK
рдФрд░ рдЕрдиреНрдпред
рдЗрд╕рдХреЗ рдмрд╛рдж рд░реЛрдорд╛, рдХреНрд╖реЗрддреНрд░реЛрдВ, ROM
рдФрд░ RAM
рдмреНрд▓реЙрдХреЛрдВ рдХреА рд╢реБрд░реБрдЖрдд рдФрд░ рдЕрдВрдд рдХреЗ рдкрддреЗ рдХреЗ рд╕рд╛рде рд╕рдВрд░рдЪрдирд╛ рдЖрддреА рд╣реИ, рдЪреЗрдХрдмреЙрдХреНрд╕ (рдХреНрд╖реЗрддреНрд░ рдбреЗрд╡рд▓рдкрд░реНрд╕ рдХреЗ рдЕрдиреБрд░реЛрдз рдкрд░ рдЪреЗрдХ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рди рдХрд┐ рдЙрдкрд╕рд░реНрдЧ) рдФрд░ рдЕрдиреНрдп рдЬрд╛рдирдХрд╛рд░реАред
рдЖрдЗрдП рдЗрди рд╕рдВрд░рдЪрдирд╛рдУрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП java
рдХрдХреНрд╖рд╛рдПрдВ рдмрдирд╛рдПрдВ, рд╕рд╛рде рд╣реА рдЙрди рдбреЗрдЯрд╛ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЬрд┐рдиреНрд╣реЗрдВ рд╕рдВрд░рдЪрдирд╛рдУрдВ рдХреА рд╕реВрдЪреА рдореЗрдВ рдЬреЛрдбрд╝рд╛ рдЬрд╛рдПрдЧрд╛ред
VectorsTable
рд╣рдо рдПрдХ рдирдпрд╛ рд╡рд░реНрдЧ VectorsTable
, рдФрд░, рдзреНрдпрд╛рди рджреЗрддреЗ рд╣реИрдВ, рд╣рдо рд╕рдВрдХреЗрдд рджреЗрддреЗ рд╣реИрдВ рдХрд┐ рдпрд╣ StructConverter
рдЗрдВрдЯрд░рдлреЗрд╕ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддрд╛ рд╣реИред рдЗрд╕ рд╡рд░реНрдЧ рдореЗрдВ рд╣рдо рд╡реИрдХреНрдЯрд░ рдХреЗ рдкрддреЗ (рднрд╡рд┐рд╖реНрдп рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХреЗ рд▓рд┐рдП) рдФрд░ рдЙрдирдХреЗ рдирд╛рдо рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░реЗрдВрдЧреЗред

рд╣рдо рд╡реЗрдХреНрдЯрд░ рдирд╛рдореЛрдВ рдФрд░ рдЙрдирдХреА рд╕рдВрдЦреНрдпрд╛ рдХреА рдПрдХ рд╕реВрдЪреА рдШреЛрд╖рд┐рдд рдХрд░рддреЗ рд╣реИрдВ:
private static final int VECTORS_SIZE = 0x100; private static final int VECTORS_COUNT = VECTORS_SIZE / 4; private static final String[] VECTOR_NAMES = { "SSP", "Reset", "BusErr", "AdrErr", "InvOpCode", "DivBy0", "Check", "TrapV", "GPF", "Trace", "Reserv0", "Reserv1", "Reserv2", "Reserv3", "Reserv4", "BadInt", "Reserv10", "Reserv11", "Reserv12", "Reserv13", "Reserv14", "Reserv15", "Reserv16", "Reserv17", "BadIRQ", "IRQ1", "EXT", "IRQ3", "HBLANK", "IRQ5", "VBLANK", "IRQ7", "Trap0", "Trap1", "Trap2", "Trap3", "Trap4", "Trap5", "Trap6", "Trap7", "Trap8", "Trap9", "Trap10", "Trap11", "Trap12", "Trap13","Trap14", "Trap15", "Reserv30", "Reserv31", "Reserv32", "Reserv33", "Reserv34", "Reserv35", "Reserv36", "Reserv37", "Reserv38", "Reserv39", "Reserv3A", "Reserv3B", "Reserv3C", "Reserv3D", "Reserv3E", "Reserv3F" };
рд╣рдо рдкрддреЗ рдФрд░ рд╡реЗрдХреНрдЯрд░ рдирд╛рдо рдХреЗ рднрдВрдбрд╛рд░рдг рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрд▓рдЧ рд╡рд░реНрдЧ рдмрдирд╛рддреЗ рд╣реИрдВ:
package sega; import ghidra.program.model.address.Address; public class VectorFunc { private Address address; private String name; public VectorFunc(Address address, String name) { this.address = address; this.name = name; } public Address getAddress() { return address; } public String getName() { return name; } }
рд╡реИрдХреНрдЯрд░ рдХреА рд╕реВрдЪреА vectors
рд╕рд░рдгреА рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рдХреА рдЬрд╛рдПрдЧреА:
private VectorFunc[] vectors;
рдирд┐рд░реНрдорд╛рддрд╛ рдХреЗ рд▓рд┐рдП VectorsTable
рд╣реЛрдЧрд╛:
FlatProgramAPI fpa
рд╣рд╛рдЗрдбреНрд░рд╛ рдХреЗ Address
рдбреЗрдЯрд╛ рдкреНрд░рдХрд╛рд░ рдХреЗ рд▓рд┐рдП long
рдкрддреЗ рдХреЛ рдмрджрд▓рдиреЗ рдХреЗ рд▓рд┐рдП FlatProgramAPI fpa
(рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдпрд╣ рдбреЗрдЯрд╛ рдкреНрд░рдХрд╛рд░ рдкрддреЗ рдХреЗ рд╕рд░рд▓ рд╕рдВрдЦреНрдпрд╛рддреНрдордХ рдорд╛рди рдХреЛ рдХрд┐рд╕реА рдЕрдиреНрдп рдЪрд┐рдк рд╕реЗ FlatProgramAPI fpa
рдкреВрд░рдХ рдХрд░рддрд╛ рд╣реИ - рдкрддрд╛ рд╕реНрдерд╛рди)BinaryReader reader
- рд░реАрдбрд┐рдВрдЧ рдпрд╛рд░реНрдб
toAddr()
рдСрдмреНрдЬреЗрдХреНрдЯ рдореЗрдВ рдПрдХ toAddr()
рд╡рд┐рдзрд┐ рд╣реИ, рдФрд░ reader
рдиреЗ setPointerIndex()
рдФрд░ readNextUnsignedInt()
ред рд╕рд┐рджреНрдзрд╛рдВрдд рд░реВрдк рдореЗрдВ, рдЕрдзрд┐рдХ рдХреБрдЫ рднреА рдЖрд╡рд╢реНрдпрдХ рдирд╣реАрдВ рд╣реИред рд╣рдореЗрдВ рдХреЛрдб рдорд┐рд▓рддрд╛ рд╣реИ:
public VectorsTable(FlatProgramAPI fpa, BinaryReader reader) throws IOException { if (reader.length() < VECTORS_COUNT) { return; } reader.setPointerIndex(0); vectors = new VectorFunc[VECTORS_COUNT]; for (int i = 0; i < VECTORS_COUNT; ++i) { vectors[i] = new VectorFunc(fpa.toAddr(reader.readNextUnsignedInt()), VECTOR_NAMES[i]); } }
toDataType()
рд╡рд┐рдзрд┐, рдЬрд┐рд╕реЗ рд╣рдореЗрдВ рд╕рдВрд░рдЪрдирд╛ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдУрд╡рд░рд░рд╛рдЗрдб рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдХреЛ рдПрдХ Structure
рдСрдмреНрдЬреЗрдХреНрдЯ рд╡рд╛рдкрд╕ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП рдЬрд┐рд╕рдореЗрдВ рд╕рдВрд░рдЪрдирд╛ рдлрд╝реАрд▓реНрдб рдХреЗ рдирд╛рдо, рдЙрдирдХреЗ рдЖрдХрд╛рд░, рдФрд░ рдкреНрд░рддреНрдпреЗрдХ рдлрд╝реАрд▓реНрдб рдкрд░ рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдХреЛ рдШреЛрд╖рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП (рдЖрдк null
рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ):
@Override public DataType toDataType() { Structure s = new StructureDataType("VectorsTable", 0); for (int i = 0; i < VECTORS_COUNT; ++i) { s.add(POINTER, 4, VECTOR_NAMES[i], null); } return s; }
рдареАрдХ рд╣реИ, рдЪрд▓реЛ рдкреНрд░рддреНрдпреЗрдХ рд╡реИрдХреНрдЯрд░, рдпрд╛ рдкреВрд░реА рд╕реВрдЪреА (рдмреЙрдпрд▓рд░рдкреНрд▓реЗрдЯ рдХреЛрдб рдХрд╛ рдПрдХ рдЧреБрдЪреНрдЫрд╛) рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рддрд░реАрдХреЛрдВ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╣реИрдВ:
рдЕрдиреНрдп рд╡рд┐рдзрд┐рдпрд╛рдБ public VectorFunc[] getVectors() { return vectors; } public VectorFunc getSSP() { if (vectors.length < 1) { return null; } return vectors[0]; } public VectorFunc getReset() { if (vectors.length < 2) { return null; } return vectors[1]; } public VectorFunc getBusErr() { if (vectors.length < 3) { return null; } return vectors[2]; } public VectorFunc getAdrErr() { if (vectors.length < 4) { return null; } return vectors[3]; } public VectorFunc getInvOpCode() { if (vectors.length < 5) { return null; } return vectors[4]; } public VectorFunc getDivBy0() { if (vectors.length < 6) { return null; } return vectors[5]; } public VectorFunc getCheck() { if (vectors.length < 7) { return null; } return vectors[6]; } public VectorFunc getTrapV() { if (vectors.length < 8) { return null; } return vectors[7]; } public VectorFunc getGPF() { if (vectors.length < 9) { return null; } return vectors[8]; } public VectorFunc getTrace() { if (vectors.length < 10) { return null; } return vectors[9]; } public VectorFunc getReserv0() { if (vectors.length < 11) { return null; } return vectors[10]; } public VectorFunc getReserv1() { if (vectors.length < 12) { return null; } return vectors[11]; } public VectorFunc getReserv2() { if (vectors.length < 13) { return null; } return vectors[12]; } public VectorFunc getReserv3() { if (vectors.length < 14) { return null; } return vectors[13]; } public VectorFunc getReserv4() { if (vectors.length < 15) { return null; } return vectors[14]; } public VectorFunc getBadInt() { if (vectors.length < 16) { return null; } return vectors[15]; } public VectorFunc getReserv10() { if (vectors.length < 17) { return null; } return vectors[16]; } public VectorFunc getReserv11() { if (vectors.length < 18) { return null; } return vectors[17]; } public VectorFunc getReserv12() { if (vectors.length < 19) { return null; } return vectors[18]; } public VectorFunc getReserv13() { if (vectors.length < 20) { return null; } return vectors[19]; } public VectorFunc getReserv14() { if (vectors.length < 21) { return null; } return vectors[20]; } public VectorFunc getReserv15() { if (vectors.length < 22) { return null; } return vectors[21]; } public VectorFunc getReserv16() { if (vectors.length < 23) { return null; } return vectors[22]; } public VectorFunc getReserv17() { if (vectors.length < 24) { return null; } return vectors[23]; } public VectorFunc getBadIRQ() { if (vectors.length < 25) { return null; } return vectors[24]; } public VectorFunc getIRQ1() { if (vectors.length < 26) { return null; } return vectors[25]; } public VectorFunc getEXT() { if (vectors.length < 27) { return null; } return vectors[26]; } public VectorFunc getIRQ3() { if (vectors.length < 28) { return null; } return vectors[27]; } public VectorFunc getHBLANK() { if (vectors.length < 29) { return null; } return vectors[28]; } public VectorFunc getIRQ5() { if (vectors.length < 30) { return null; } return vectors[29]; } public VectorFunc getVBLANK() { if (vectors.length < 31) { return null; } return vectors[30]; } public VectorFunc getIRQ7() { if (vectors.length < 32) { return null; } return vectors[31]; } public VectorFunc getTrap0() { if (vectors.length < 33) { return null; } return vectors[32]; } public VectorFunc getTrap1() { if (vectors.length < 34) { return null; } return vectors[33]; } public VectorFunc getTrap2() { if (vectors.length < 35) { return null; } return vectors[34]; } public VectorFunc getTrap3() { if (vectors.length < 36) { return null; } return vectors[35]; } public VectorFunc getTrap4() { if (vectors.length < 37) { return null; } return vectors[36]; } public VectorFunc getTrap5() { if (vectors.length < 38) { return null; } return vectors[37]; } public VectorFunc getTrap6() { if (vectors.length < 39) { return null; } return vectors[38]; } public VectorFunc getTrap7() { if (vectors.length < 40) { return null; } return vectors[39]; } public VectorFunc getTrap8() { if (vectors.length < 41) { return null; } return vectors[40]; } public VectorFunc getTrap9() { if (vectors.length < 42) { return null; } return vectors[41]; } public VectorFunc getTrap10() { if (vectors.length < 43) { return null; } return vectors[42]; } public VectorFunc getTrap11() { if (vectors.length < 44) { return null; } return vectors[43]; } public VectorFunc getTrap12() { if (vectors.length < 45) { return null; } return vectors[44]; } public VectorFunc getTrap13() { if (vectors.length < 46) { return null; } return vectors[45]; } public VectorFunc getTrap14() { if (vectors.length < 47) { return null; } return vectors[46]; } public VectorFunc getTrap15() { if (vectors.length < 48) { return null; } return vectors[47]; } public VectorFunc getReserv30() { if (vectors.length < 49) { return null; } return vectors[48]; } public VectorFunc getReserv31() { if (vectors.length < 50) { return null; } return vectors[49]; } public VectorFunc getReserv32() { if (vectors.length < 51) { return null; } return vectors[50]; } public VectorFunc getReserv33() { if (vectors.length < 52) { return null; } return vectors[51]; } public VectorFunc getReserv34() { if (vectors.length < 53) { return null; } return vectors[52]; } public VectorFunc getReserv35() { if (vectors.length < 54) { return null; } return vectors[53]; } public VectorFunc getReserv36() { if (vectors.length < 55) { return null; } return vectors[54]; } public VectorFunc getReserv37() { if (vectors.length < 56) { return null; } return vectors[55]; } public VectorFunc getReserv38() { if (vectors.length < 57) { return null; } return vectors[56]; } public VectorFunc getReserv39() { if (vectors.length < 58) { return null; } return vectors[57]; } public VectorFunc getReserv3A() { if (vectors.length < 59) { return null; } return vectors[58]; } public VectorFunc getReserv3B() { if (vectors.length < 60) { return null; } return vectors[59]; } public VectorFunc getReserv3C() { if (vectors.length < 61) { return null; } return vectors[60]; } public VectorFunc getReserv3D() { if (vectors.length < 62) { return null; } return vectors[61]; } public VectorFunc getReserv3E() { if (vectors.length < 63) { return null; } return vectors[62]; } public VectorFunc getReserv3F() { if (vectors.length < 64) { return null; } return vectors[63]; }
рд╣рдо рдРрд╕рд╛ рд╣реА рдХрд░реЗрдВрдЧреЗ рдФрд░ рдПрдХ GameHeader
рдХреНрд▓рд╛рд╕ GameHeader
рдЬреЛ рдХрд┐ StructConverter
рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддрд╛ рд╣реИред
рдЦреЗрд▓ рд░рдо рд╣реЗрдбрд░ рд╕рдВрд░рдЪрдирд╛рдСрдлрд╝рд╕реЗрдЯ рдкреНрд░рд╛рд░рдВрдн рдХрд░реЗрдВ | рд╕рдорд╛рдкреНрддрд┐ рдСрдлрд╕реЗрдЯ | рд╡рд┐рд╡рд░рдг |
---|
$ 100 | $ 10F | рдХрдВрд╕реЛрд▓ рдирд╛рдо (рдЖрдорддреМрд░ рдкрд░ 'SEGA рдореЗрдЧрд╛ рдбреНрд░рд╛рдЗрд╡' рдпрд╛ 'SEGA рдЙрддреНрдкрддреНрддрд┐') |
$ 110 | $ 11F | рд░рд┐рд▓реАрдЬ рдХреА рддрд╛рд░реАрдЦ (рдЖрдорддреМрд░ рдкрд░ '┬й XXXX YYYY.MMM' рдЬрд╣рд╛рдВ XXXX рдХрдВрдкрдиреА рдХреЛрдб рд╣реИ, YYYY рд╡рд░реНрд╖ рдФрд░ MMM - рдорд╣реАрдирд╛ рд╣реИ) |
$ 120 | $ 14F | рдШрд░реЗрд▓реВ рдирд╛рдо |
$ 150 | $ 17F | рдЕрдВрддрд░реНрд░рд╛рд╖реНрдЯреНрд░реАрдп рдирд╛рдо |
$ 180 | $ 18 рдбреА | рд╕рдВрд╕реНрдХрд░рдг ('XX YYYYYYYYYYYY' рдЬрд╣рд╛рдВ XX рдЧреЗрдо рдХрд╛ рдкреНрд░рдХрд╛рд░ рд╣реИ рдФрд░ YY рдЧреЗрдо рдХреЛрдб рд╣реИ) |
$ 18 рдИ | $ 18F | checksum |
$ 190 | $ 19F | рдореИрдВ / рдУ рд╕рдорд░реНрдерди |
$ 1 рдП 0 | $ 1 рдП 3 | рд░реЛрдо рдкреНрд░рд╛рд░рдВрдн |
$ 1 рдП 4 | $ 1 рдП 7 | рд░реЛрдо рдЕрдВрдд |
$ 1 рдП 8 | $ 1AB | RAM рдкреНрд░рд╛рд░рдВрдн (рдЖрдорддреМрд░ рдкрд░ $ 00FF0000) |
$ 1AC | $ 1AF | RAM рдЕрдВрдд (рдЖрдорддреМрд░ рдкрд░ $ 00FFFFFF) |
$ 1B0 | $ 1 рдмреА 2 | 'RA' рдФрд░ $ F8 SRAM рдХреЛ рд╕рдХреНрд╖рдо рдмрдирд╛рддрд╛ рд╣реИ |
$ 1 рдмреА 3 | ---- | рдЕрдкреНрд░рдпреБрдХреНрдд ($ 20) |
$ 1B4 | $ 1 рдмреА 7 | SRAM рдкреНрд░рд╛рд░рдВрдн (рдбрд┐рдлрд╝реЙрд▓реНрдЯ $ 00200000) |
$ 1 рдмреА 8 | $ 1BB | SRAM рдЕрдВрдд (рдбрд┐рдлрд╝реЙрд▓реНрдЯ $ 0020FFFF) |
$ 1BC | $ 1FF | рдиреЛрдЯреНрд╕ (рдЕрдкреНрд░рдпреБрдХреНрдд) |
рд╣рдо рдлрд╝реАрд▓реНрдб рд╕реЗрдЯ рдХрд░рддреЗ рд╣реИрдВ, рдЗрдирдкреБрдЯ рдбреЗрдЯрд╛ рдХреА рдкрд░реНрдпрд╛рдкреНрдд рд▓рдВрдмрд╛рдИ рдХреА рдЬрд╛рдБрдЪ рдХрд░рддреЗ рд╣реИрдВ, рд╣рдорд╛рд░реЗ рд▓рд┐рдП рджреЛ рдирдП рддрд░реАрдХреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ readNextByteArray()
, readNextUnsignedShort()
reader
рдСрдмреНрдЬреЗрдХреНрдЯ рдХрд╛ рдбреЗрдЯрд╛ рдкрдврд╝рдиреЗ рдХреЗ рд▓рд┐рдП, рдФрд░ рдПрдХ рд╕рдВрд░рдЪрдирд╛ рдмрдирд╛рдПрдБред рдкрд░рд┐рдгрд╛рдореА рдХреЛрдб рдЗрд╕ рдкреНрд░рдХрд╛рд░ рд╣реИ:
GameHeader package sega; import java.io.IOException; import ghidra.app.util.bin.BinaryReader; import ghidra.app.util.bin.StructConverter; import ghidra.program.flatapi.FlatProgramAPI; import ghidra.program.model.address.Address; import ghidra.program.model.data.DataType; import ghidra.program.model.data.Structure; import ghidra.program.model.data.StructureDataType; public class GameHeader implements StructConverter { private byte[] consoleName = null; private byte[] releaseDate = null; private byte[] domesticName = null; private byte[] internationalName = null; private byte[] version = null; private short checksum = 0; private byte[] ioSupport = null; private Address romStart = null, romEnd = null; private Address ramStart = null, ramEnd = null; private byte[] sramCode = null; private byte unused = 0; private Address sramStart = null, sramEnd = null; private byte[] notes = null; FlatProgramAPI fpa; public GameHeader(FlatProgramAPI fpa, BinaryReader reader) throws IOException { this.fpa = fpa; if (reader.length() < 0x200) { return; } reader.setPointerIndex(0x100); consoleName = reader.readNextByteArray(0x10); releaseDate = reader.readNextByteArray(0x10); domesticName = reader.readNextByteArray(0x30); internationalName = reader.readNextByteArray(0x30); version = reader.readNextByteArray(0x0E); checksum = (short) reader.readNextUnsignedShort(); ioSupport = reader.readNextByteArray(0x10); romStart = fpa.toAddr(reader.readNextUnsignedInt()); romEnd = fpa.toAddr(reader.readNextUnsignedInt()); ramStart = fpa.toAddr(reader.readNextUnsignedInt()); ramEnd = fpa.toAddr(reader.readNextUnsignedInt()); sramCode = reader.readNextByteArray(0x03); unused = reader.readNextByte(); sramStart = fpa.toAddr(reader.readNextUnsignedInt()); sramEnd = fpa.toAddr(reader.readNextUnsignedInt()); notes = reader.readNextByteArray(0x44); } @Override public DataType toDataType() { Structure s = new StructureDataType("GameHeader", 0); s.add(STRING, 0x10, "ConsoleName", null); s.add(STRING, 0x10, "ReleaseDate", null); s.add(STRING, 0x30, "DomesticName", null); s.add(STRING, 0x30, "InternationalName", null); s.add(STRING, 0x0E, "Version", null); s.add(WORD, 0x02, "Checksum", null); s.add(STRING, 0x10, "IoSupport", null); s.add(POINTER, 0x04, "RomStart", null); s.add(POINTER, 0x04, "RomEnd", null); s.add(POINTER, 0x04, "RamStart", null); s.add(POINTER, 0x04, "RamEnd", null); s.add(STRING, 0x03, "SramCode", null); s.add(BYTE, 0x01, "Unused", null); s.add(POINTER, 0x04, "SramStart", null); s.add(POINTER, 0x04, "SramEnd", null); s.add(STRING, 0x44, "Notes", null); return s; } public byte[] getConsoleName() { return consoleName; } public byte[] getReleaseDate() { return releaseDate; } public byte[] getDomesticName() { return domesticName; } public byte[] getInternationalName() { return internationalName; } public byte[] getVersion() { return version; } public short getChecksum() { return checksum; } public byte[] getIoSupport() { return ioSupport; } public Address getRomStart() { return romStart; } public Address getRomEnd() { return romEnd; } public Address getRamStart() { return ramStart; } public Address getRamEnd() { return ramEnd; } public byte[] getSramCode() { return sramCode; } public byte getUnused() { return unused; } public Address getSramStart() { return sramStart; } public Address getSramEnd() { return sramEnd; } public boolean hasSRAM() { if (sramCode == null) { return false; } return sramCode[0] == 'R' && sramCode[1] == 'A' && sramCode[2] == 0xF8; } public byte[] getNotes() { return notes; } }
рд╣реЗрдбрд░ рдХреЗ рд▓рд┐рдП рдСрдмреНрдЬреЗрдХреНрдЯ рдмрдирд╛рдПрдБ:
vectors = new VectorsTable(fpa, reader); header = new GameHeader(fpa, reader);
рдЦрдВрдбреЛрдВ
рд╕реЗрдЧрд╛ рдХреЗ рдкрд╛рд╕ рд╕реНрдореГрддрд┐ рдХреНрд╖реЗрддреНрд░реЛрдВ рдХрд╛ рдПрдХ рдкреНрд░рд╕рд┐рджреНрдз рдорд╛рдирдЪрд┐рддреНрд░ рд╣реИ, рдЬрд┐рд╕реЗ рдореИрдВ, рд╢рд╛рдпрдж, рдпрд╣рд╛рдВ рддрд╛рд▓рд┐рдХрд╛ рдХреЗ рд░реВрдк рдореЗрдВ рдирд╣реАрдВ рджреВрдВрдЧрд╛, рд▓реЗрдХрд┐рди рдореИрдВ рдХреЗрд╡рд▓ рд╡рд╣ рдХреЛрдб рджреВрдВрдЧрд╛ рдЬреЛ рдХрд┐ рд╕реЗрдЧрдореЗрдВрдЯ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
рддреЛ, FlatProgramAPI
рд╡рд░реНрдЧ рдХреЗ рдСрдмреНрдЬреЗрдХреНрдЯ рдореЗрдВ рдПрдХ createMemoryBlock()
рд╡рд┐рдзрд┐ рд╣реИ, рдЬрд┐рд╕рдХреЗ рд╕рд╛рде рдореЗрдореЛрд░реА рдХреНрд╖реЗрддреНрд░ рдмрдирд╛рдирд╛ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╣реИред рдЗрдирдкреБрдЯ рдкрд░, рдпрд╣ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рддрд░реНрдХ рд▓реЗрддрд╛ рд╣реИ:
name
: рдХреНрд╖реЗрддреНрд░ рдХрд╛ рдирд╛рдоaddress
: рдХреНрд╖реЗрддреНрд░ рдХрд╛ рдкрддрд╛ рд╢реБрд░реВ рдХрд░реЗрдВstream
: рдЯрд╛рдЗрдк InputStream
рдХрд╛ рдПрдХ рдСрдмреНрдЬреЗрдХреНрдЯ, рдЬреЛ рдореЗрдореЛрд░реА рдХреЗ рдХреНрд╖реЗрддреНрд░ рдореЗрдВ рдбреЗрдЯрд╛ рдХреЗ рд▓рд┐рдП рдЖрдзрд╛рд░ рд╣реЛрдЧрд╛ред рдпрджрд┐ рдЖрдк null
рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдПрдХ рдЕрд╕рд┐рдВрдЪрд┐рдд рдХреНрд╖реЗрддреНрд░ рдмрдирд╛рдпрд╛ рдЬрд╛рдПрдЧрд╛ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, 68K RAM
рдпрд╛ Z80 RAM
рд╣рдореЗрдВ рдмрд╕ рдЙрд╕реА рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреАsize
: рдирд┐рд░реНрдорд┐рдд рдХреНрд╖реЗрддреНрд░ рдХрд╛ рдЖрдХрд╛рд░isOverlay
: true
рдпрд╛ false
рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рддрд╛ true
, рдФрд░ рдЗрдВрдЧрд┐рдд рдХрд░рддрд╛ рд╣реИ рдХрд┐ рдореЗрдореЛрд░реА рдХреНрд╖реЗрддреНрд░ рдУрд╡рд░рд▓реЗ рд╣реИред рдореБрдЭреЗ рдкрддрд╛ рдирд╣реАрдВ рд╣реИ рдХрд┐ рдирд┐рд╖реНрдкрд╛рджрди рдпреЛрдЧреНрдп рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЛ рдЫреЛрдбрд╝рдХрд░ рдЗрд╕рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдХрд╣рд╛рдВ рд╣реИ
рдЖрдЙрдЯрдкреБрдЯ рдкрд░, createMemoryBlock()
рдПрдХ MemoryBlock
рдкреНрд░рдХрд╛рд░ рдХрд╛ рдСрдмреНрдЬреЗрдХреНрдЯ MemoryBlock
, рдЬрд┐рд╕рдореЗрдВ рдЖрдк рд╡реИрдХрд▓реНрдкрд┐рдХ рд░реВрдк рд╕реЗ рдПрдХреНрд╕реЗрд╕ рд░рд╛рдЗрдЯреНрд╕ рдлреНрд▓реИрдЧ ( Read
, Write
, createMemoryBlock()
рд╕реЗрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк, рд╣рдореЗрдВ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдлрд╝реЙрд░реНрдо рдХрд╛ рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдорд┐рд▓рддрд╛ рд╣реИ:
private void createSegment(FlatProgramAPI fpa, InputStream stream, String name, Address address, long size, boolean read, boolean write, boolean execute) { MemoryBlock block = null; try { block = fpa.createMemoryBlock(name, address, stream, size, false); block.setRead(read); block.setWrite(read); block.setExecute(execute); } catch (Exception e) { Msg.error(this, String.format("Error creating %s segment", name)); } }
рдпрд╣рд╛рдБ рд╣рдордиреЗ рдЕрддрд┐рд░рд┐рдХреНрдд рд░реВрдк рд╕реЗ рдПрдХ рддреНрд░реБрдЯрд┐ рд╕рдВрджреЗрд╢ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП Msg
рд╡рд░реНрдЧ рдХреА рд╕реНрдереИрддрд┐рдХ error
рд╡рд┐рдзрд┐ рдХреЛ рдХрд╣рд╛ рд╣реИред
рдЧреЗрдо рд░рдо рд╡рд╛рд▓реЗ рд╕реЗрдЧрдореЗрдВрдЯ рдореЗрдВ рдЕрдзрд┐рдХрддрдо рдЖрдХрд╛рд░ 0x3FFFFF
(рдмрд╛рдХреА рд╕рдм рдХреБрдЫ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЕрдиреНрдп рдХреНрд╖реЗрддреНрд░реЛрдВ рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рд╣реЛрдЧрд╛)ред рдЖрдЗрдП рдЗрд╕реЗ рдмрдирд╛рдПрдВ:
InputStream romStream = provider.getInputStream(0); createSegment(fpa, romStream, "ROM", fpa.toAddr(0x000000), Math.min(romStream.available(), 0x3FFFFF), true, false, true);
InputStream
, 0.
, ( SegaCD
Sega32X
). OptionDialog
. , showYesNoDialogWithNoAsDefaultButton()
YES
NO
- NO
.
:
if (OptionDialog.YES_OPTION == OptionDialog.showYesNoDialogWithNoAsDefaultButton(null, "Question", "Create Sega CD segment?")) { if (romStream.available() > 0x3FFFFF) { InputStream epaStream = provider.getInputStream(0x400000); createSegment(fpa, epaStream, "EPA", fpa.toAddr(0x400000), 0x400000, true, true, false); } else { createSegment(fpa, null, "EPA", fpa.toAddr(0x400000), 0x400000, true, true, false); } } if (OptionDialog.YES_OPTION == OptionDialog.showYesNoDialogWithNoAsDefaultButton(null, "Question", "Create Sega 32X segment?")) { createSegment(fpa, null, "32X", fpa.toAddr(0x800000), 0x200000, true, true, false); }
:
createSegment(fpa, null, "Z80", fpa.toAddr(0xA00000), 0x10000, true, true, false); createSegment(fpa, null, "SYS1", fpa.toAddr(0xA10000), 16 * 2, true, true, false); createSegment(fpa, null, "SYS2", fpa.toAddr(0xA11000), 2, true, true, false); createSegment(fpa, null, "Z802", fpa.toAddr(0xA11100), 2, true, true, false); createSegment(fpa, null, "Z803", fpa.toAddr(0xA11200), 2, true, true, false); createSegment(fpa, null, "FDC", fpa.toAddr(0xA12000), 0x100, true, true, false); createSegment(fpa, null, "TIME", fpa.toAddr(0xA13000), 0x100, true, true, false); createSegment(fpa, null, "TMSS", fpa.toAddr(0xA14000), 4, true, true, false); createSegment(fpa, null, "VDP", fpa.toAddr(0xC00000), 2 * 9, true, true, false); createSegment(fpa, null, "RAM", fpa.toAddr(0xFF0000), 0x10000, true, true, true); if (header.hasSRAM()) { Address sramStart = header.getSramStart(); Address sramEnd = header.getSramEnd(); if (sramStart.getOffset() >= 0x200000 && sramEnd.getOffset() <= 0x20FFFF && sramStart.getOffset() < sramEnd.getOffset()) { createSegment(fpa, null, "SRAM", sramStart, sramEnd.getOffset() - sramStart.getOffset() + 1, true, true, false); } }
,
CreateArrayCmd
. , :
address
: ,numElements
:dataType
:elementSize
:
applyTo(program)
, .
, , BYTE
, WORD
, DWORD
. , FlatProgramAPI
createByte()
, createWord()
, createDword()
..
, , (, VDP
). , :
Program
getSymbolTable()
, , ..createLabel()
, , . , , SourceType.IMPORTED
, :
private void createNamedByteArray(FlatProgramAPI fpa, Program program, Address address, String name, int numElements) { if (numElements > 1) { CreateArrayCmd arrayCmd = new CreateArrayCmd(address, numElements, ByteDataType.dataType, ByteDataType.dataType.getLength()); arrayCmd.applyTo(program); } else { try { fpa.createByte(address); } catch (Exception e) { Msg.error(this, "Cannot create byte. " + e.getMessage()); } } try { program.getSymbolTable().createLabel(address, name, SourceType.IMPORTED); } catch (InvalidInputException e) { Msg.error(this, String.format("%s : Error creating array %s", getName(), name)); } } private void createNamedWordArray(FlatProgramAPI fpa, Program program, Address address, String name, int numElements) { if (numElements > 1) { CreateArrayCmd arrayCmd = new CreateArrayCmd(address, numElements, WordDataType.dataType, WordDataType.dataType.getLength()); arrayCmd.applyTo(program); } else { try { fpa.createWord(address); } catch (Exception e) { Msg.error(this, "Cannot create word. " + e.getMessage()); } } try { program.getSymbolTable().createLabel(address, name, SourceType.IMPORTED); } catch (InvalidInputException e) { Msg.error(this, String.format("%s : Error creating array %s", getName(), name)); } } private void createNamedDwordArray(FlatProgramAPI fpa, Program program, Address address, String name, int numElements) { if (numElements > 1) { CreateArrayCmd arrayCmd = new CreateArrayCmd(address, numElements, DWordDataType.dataType, DWordDataType.dataType.getLength()); arrayCmd.applyTo(program); } else { try { fpa.createDWord(address); } catch (Exception e) { Msg.error(this, "Cannot create dword. " + e.getMessage()); } } try { program.getSymbolTable().createLabel(address, name, SourceType.IMPORTED); } catch (InvalidInputException e) { Msg.error(this, String.format("%s : Error creating array %s", getName(), name)); } }
createNamedDwordArray(fpa, program, fpa.toAddr(0xA04000), "Z80_YM2612", 1); createNamedWordArray(fpa, program, fpa.toAddr(0xA10000), "IO_PCBVER", 1); createNamedWordArray(fpa, program, fpa.toAddr(0xA10002), "IO_CT1_DATA", 1); createNamedWordArray(fpa, program, fpa.toAddr(0xA10004), "IO_CT2_DATA", 1); createNamedWordArray(fpa, program, fpa.toAddr(0xA10006), "IO_EXT_DATA", 1); createNamedWordArray(fpa, program, fpa.toAddr(0xA10008), "IO_CT1_CTRL", 1); createNamedWordArray(fpa, program, fpa.toAddr(0xA1000A), "IO_CT2_CTRL", 1); createNamedWordArray(fpa, program, fpa.toAddr(0xA1000C), "IO_EXT_CTRL", 1); createNamedWordArray(fpa, program, fpa.toAddr(0xA1000E), "IO_CT1_RX", 1); createNamedWordArray(fpa, program, fpa.toAddr(0xA10010), "IO_CT1_TX", 1); createNamedWordArray(fpa, program, fpa.toAddr(0xA10012), "IO_CT1_SMODE", 1); createNamedWordArray(fpa, program, fpa.toAddr(0xA10014), "IO_CT2_RX", 1); createNamedWordArray(fpa, program, fpa.toAddr(0xA10016), "IO_CT2_TX", 1); createNamedWordArray(fpa, program, fpa.toAddr(0xA10018), "IO_CT2_SMODE", 1); createNamedWordArray(fpa, program, fpa.toAddr(0xA1001A), "IO_EXT_RX", 1); createNamedWordArray(fpa, program, fpa.toAddr(0xA1001C), "IO_EXT_TX", 1); createNamedWordArray(fpa, program, fpa.toAddr(0xA1001E), "IO_EXT_SMODE", 1); createNamedWordArray(fpa, program, fpa.toAddr(0xA11000), "IO_RAMMODE", 1); createNamedWordArray(fpa, program, fpa.toAddr(0xA11100), "IO_Z80BUS", 1); createNamedWordArray(fpa, program, fpa.toAddr(0xA11200), "IO_Z80RES", 1); createNamedByteArray(fpa, program, fpa.toAddr(0xA12000), "IO_FDC", 0x100); createNamedByteArray(fpa, program, fpa.toAddr(0xA13000), "IO_TIME", 0x100); createNamedDwordArray(fpa, program, fpa.toAddr(0xA14000), "IO_TMSS", 1); createNamedWordArray(fpa, program, fpa.toAddr(0xC00000), "VDP_DATA", 1); createNamedWordArray(fpa, program, fpa.toAddr(0xC00002), "VDP__DATA", 1); createNamedWordArray(fpa, program, fpa.toAddr(0xC00004), "VDP_CTRL", 1); createNamedWordArray(fpa, program, fpa.toAddr(0xC00006), "VDP__CTRL", 1); createNamedWordArray(fpa, program, fpa.toAddr(0xC00008), "VDP_CNTR", 1); createNamedWordArray(fpa, program, fpa.toAddr(0xC0000A), "VDP__CNTR", 1); createNamedWordArray(fpa, program, fpa.toAddr(0xC0000C), "VDP___CNTR", 1); createNamedWordArray(fpa, program, fpa.toAddr(0xC0000E), "VDP____CNTR", 1); createNamedByteArray(fpa, program, fpa.toAddr(0xC00011), "VDP_PSG", 1);
createData()
DataUtilities
. :
program
: Program
address
: ,dataType
:dataLength
: . -1
stackPointers
: true
, - . false
clearDataMode
: , (, )
: .. (, ), . FlatProgramAPI
createFunction()
, .
:
private void markVectorsTable(Program program, FlatProgramAPI fpa) { try { DataUtilities.createData(program, fpa.toAddr(0), vectors.toDataType(), -1, false, ClearDataMode.CLEAR_ALL_UNDEFINED_CONFLICT_DATA); for (VectorFunc func : vectors.getVectors()) { fpa.createFunction(func.getAddress(), func.getName()); } } catch (CodeUnitInsertionException e) { Msg.error(this, "Vectors mark conflict at 0x000000"); } } private void markHeader(Program program, FlatProgramAPI fpa) { try { DataUtilities.createData(program, fpa.toAddr(0x100), header.toDataType(), -1, false, ClearDataMode.CLEAR_ALL_UNDEFINED_CONFLICT_DATA); } catch (CodeUnitInsertionException e) { Msg.error(this, "Vectors mark conflict at 0x000100"); } }
load()
load()
setMessage()
TaskMonitor
, .
monitor.setMessage(String.format("%s : Start loading", getName()));
, :
@Override protected void load(ByteProvider provider, LoadSpec loadSpec, List<Option> options, Program program, MemoryConflictHandler handler, TaskMonitor monitor, MessageLog log) throws CancelledException, IOException { monitor.setMessage(String.format("%s : Start loading", getName())); BinaryReader reader = new BinaryReader(provider, false); FlatProgramAPI fpa = new FlatProgramAPI(program, monitor); vectors = new VectorsTable(fpa, reader); header = new GameHeader(fpa, reader); createSegments(fpa, provider, program, monitor); markVectorsTable(program, fpa); markHeader(program, fpa); monitor.setMessage(String.format("%s : Loading done", getName())); }
getDefaultOptions validateOptions
,
Run
-> Debug As
-> 1 Ghidra
. .

GHIDRA
, - . Eclipse
extension.properties
, :
description=Loader for Sega Mega Drive / Genesis ROMs author=Dr. MefistO createdOn=20.03.2019
GhidraDev
-> Export
-> Ghidra Module Extension...
:



dist
zip- (- ghidra_9.0_PUBLIC_20190320_Sega.zip
) GHIDRA
.
.
, File
-> Install Extensions...
, , . ...


github- , .
: IDA
GHIDRA
. .