categories | date | title | ||
---|---|---|---|---|
|
2020-04-01 21:25:03 +0900 |
ã¿ãæãã: Whitespaceã³ã³ãã€ã©ãäœã£ã話ã®è£åŽ |
κeenã§ããä»æããšã€ããªã«ããŒã«ã®ãã¿èšäºãæžããã®ã§ãã®ã¿ãæãããããŸããã¿ããšã¯ãã£ãŠããã»ãŒææžããªãã§ããã©ãã
Whitespaceã¯Edwin BradyãšChris Morrisã«ãã2003幎4æ1æ¥ã«çºè¡šãããèšèªã§ãã ãã®èšèªèªäœãšã€ããªã«ããŒã«ã®ãžã§ãŒã¯ãªãã§ããã å ¬åŒããŒãžã¯ããã®ã§ãããç¹ãããªãã®ã§WebArchiveãšãããã¢ã¯ã»ã¹ããŠäžããã
ç¹åŸŽãšããŠã¯ç©ºçœæåãã¿ãæåãæ¹è¡æåã ãã§æ§æãããŠããã®ã§ãããšèŠã§ã¯äœãæžããŠãªãããã«ãªãç¹ããããŸãã ããããesoteric languageã§ãã
ä»åã®ç§ã®ãšã€ããªã«ããŒã«ã®ãžã§ãŒã¯ã¯ãWhitespaceãç¥ããªã人ã«ã¯ãæ£çŽè ã«ããèŠããªãã³ãŒãã§ããïŒããWhitespaceãç¥ã£ãŠã人ã«ã¯ãWhitespaceïŒïŒããªããæžããæžãããããªãã ãïŒãããããä»æ¥ã¯ãšã€ããªã«ããŒã«ãããç§ãç¥ã£ãŠã人ã«ã¯ãWhitespaceã®ã³ã³ãã€ã©ã¯æ®éã¯ããããªããã©ã³ã€ããªããããããªãããšæãããããªçµ¶åŠãªã©ã€ã³ãçã£ãã€ããã§ãã æçµçã«ã¯ã¡ãããšåãåŠçç³»ãåºããŠãã®ã§ãžã§ãŒã¯ãã©ããããæªããã§ãã楜ããã§ããã ãããªã幞ãã§ãã å ã¿ã«ãœãŒã¹ã³ãŒãã¯4000ã³ãã³ãè¿ããããŸãã
空çœã ãšææäŒéã«é£ãããã®ã§ã以éãã®èšäºå
ã§ã¯ç©ºçœæåãã¿ãæåãæ¹è¡æåããããã s
ã t
ã n
ãšè¡šèšããŸãã
Whitespaceã¯åœä»€åã®ã¹ã¿ãã¯ãã·ã³ã§ããããŒããæ±ããŸããå€ã¯ä»»æé·ã®æŽæ°ã®ã¿ã§ãã
ããããã®ã³ãã³ãã®åã«ã¯åœä»€ä¿®é£Ÿãã©ã¡ãŒã¿ïŒInstruction Modification ParameterãIMPïŒãã€ããŸãã IMPã¯5ã€ãããã³ãã³ãã®çš®é¡ã倧å¥ããŠããŸãã
IMP | åé¡ |
---|---|
s |
ã¹ã¿ãã¯æäœ |
ts |
ç®è¡ |
tt |
ããŒãã¢ã¯ã»ã¹ |
n |
å¶åŸ¡æ§é |
tn |
I/O |
ããããã®IMPæ¯ã«ã³ãã³ãããããŸãããŸããã³ãã³ãã«ãã£ãŠã¯ãã©ã¡ãŒã¿ãåããŸãã ãã©ã¡ãŒã¿ã«ã¯æ°å€ãšã©ãã«ããããŸãã
æ°å€ã¯ç¬Šå·ïŒs
ã+㧠t
ã-ïŒã«ç¶ããŠ2é²æ°ïŒs
ã0㧠t
ã1ïŒãæžãã n
ã§çµç«¯ããŸãã2ã®è£æ°è¡šçŸã§ã¯ãªãã®ã§æ³šæããŠäžããã
ã©ãã«ã¯ s
ãš t
ã®æååã§ã n
ã§çµç«¯ããŸãã
以äžã«ãã³ãã³ããåæããŸãã ååããªããšäžäŸ¿ãªã®ã§ååãã€ããŠãããŸããããã¯ç§ç¬èªã®ãã®ãªã®ã§æ³šæããŠäžããã
ã³ãã³ã | å¥å | ãã©ã¡ãŒã¿ | æäœ |
---|---|---|---|
s |
push | æ°å€ | ã¹ã¿ãã¯ã«æ°å€ãããã·ã¥ãã |
ns |
dup | ã¹ã¿ãã¯ããããè€è£œãã | |
ts |
copy | æ°å€ | ã¹ã¿ãã¯ã®ãããããnçªç®ã®å€ãã¹ã¿ãã¯ãããã«ã³ããŒããŠããã·ã¥ãã |
nt |
swap | ã¹ã¿ãã¯ã®ããã2å€ãå ¥ãæ¿ãã | |
nn |
discard | ã¹ã¿ãã¯ã®ãããã®å€ãæšãŠã | |
tn |
slide | æ°å€ | ã¹ã¿ãã¯ã®ãããã®å€ãæ®ããŠnåã®å€ãæšãŠã |
ãã®ãã¡ã copy
ãš discard
㯠Whitespace 0.3ã§è¿œå ãããã³ãã³ãã ããã§ãã
ããã2ã€ã®ã³ãã³ãã¯ãã¢ããšããŠã¯ãããŒã«ã«å€æ°çšã®ã³ãã³ãã§ãã é¢æ°ã¯åŒæ°ã«äžããããå€ããã¹ã¿ãã¯ãã¹ã¿ãŒãããŸãã
| v1 |
| v2 |
| v3 |
+-----+
ãããã®å€ãcopyã§åç §ããªããé¢æ°ãå®è¡ããŸãã
| v3 |<-+
| v | |
| v1 | | copy 3
| v2 | |
| v3 |+-+
+-----+
ã§ãæåŸã«ããŒã«ã«å€æ°ã®äžã«è¿ãå€ãäœããŸãã
| ret |
| v1 |
| v2 |
| v3 |
+-----+
ãã®ç¶æ ã§discardãåŒã¶ãšããã¬ã€ã«è¿ãå€ãåŒã³åºãå ã«è¿ããèš³ã§ãã
discard 3
| ret |
+-----+
2å€æ¶è²»ããŠ1å€ãçæããã³ãã³ãã§ãã
ã³ãã³ã | å¥å | ãã©ã¡ãŒã¿ | æäœ |
---|---|---|---|
ss |
add | 足ãç® (top[1] + top[0]) | |
st |
sub | åŒãç® (top[1] - top[0]) | |
sn |
mul | æãç® (top[1] * top[0]) | |
ts |
div | å²ãç® (top[1] / top[0]) | |
tt |
mod | ä¹äœç® (top[1] % top[0]) |
ã³ãã³ã | å¥å | ãã©ã¡ãŒã¿ | æäœ |
---|---|---|---|
s |
store | ããŒãã«å€ãä¿åãã (heap[stack[1]] <- stack[0] ) | |
t |
retrieve | ããŒãããå€ããšã£ãŠãã (stack.push(heap[stack[0]])) |
ã³ãã³ã | å¥å | ãã©ã¡ãŒã¿ | æäœ |
---|---|---|---|
ss |
label | ã©ãã« | ããã°ã©ã ã«ã©ãã«ãã€ãã |
st |
call | ã©ãã« | ã³ãŒã«ã¹ã¿ãã¯ã«ä»ã®ããã°ã©ã ã®å Žæãèšé²ããã©ãã«ã«é£ã¶ |
sn |
jump | ã©ãã« | ã©ãã«ã«é£ã¶ |
ts |
jz | ã©ãã« | ã¹ã¿ãã¯ãããã0ãªãã©ãã«ã«é£ã¶ |
tt |
jneg | ã©ãã« | ã¹ã¿ãã¯ããããè² ãªãã©ãã«ã«é£ã¶ |
tn |
ret | callã«åŒå¿ããèšé²ãããããã°ã©ã ã®å Žæã«æ»ã | |
nn |
end | ããã°ã©ã ãçµäºãã |
call
ãš ret
ãããã®ã§æã£ãããããã¢ãªããã°ã©ãã³ã°ãã§ããŸãã
ã³ãã³ã | å¥å | ãã©ã¡ãŒã¿ | æäœ |
---|---|---|---|
ss |
outchar | ã¹ã¿ãã¯ããããæåãšããŠåºåãã | |
st |
outnumber | ã¹ã¿ãã¯ããããæ°å€ãšããŠåºåãã | |
ts |
readchar | æåãèªãã§ãããŒãã®æå®ãããã¢ãã¬ã¹ã«çœ®ã | |
tt |
readnumber | æ°å€ãèªãã§ãããŒãã®æå®ãããã¢ãã¬ã¹ã«çœ®ã |
ãšããžã±ãŒã¹ã®ä»æ§ãäžããããŠãªãã®ã§å®è£ ããçŽè§£ããŸãã
ãªãã¡ã¬ã³ã¹ã«ã§ããããªå®è£ ã¯ãWebArchiveãã蟿ãããªãªãžãã«ïŒHaskellå®è£ ïŒãšãWhitespaceäœè ã«ããIdriså®è£ ããããŸããããããèªãã§ã¿ãŸãã
- æªåæåã®ããŒããèªãã ãšãã¯0ãè¿ããšããšè¿ããªããšãããããã
- Idriså®è£ ã¯0ãè¿ããŠããHaskellå®è£ ä»ãŸã§ã«storeããããŒãã¢ãã¬ã¹ã®æ倧å€ä»¥äžãªã0ãæ倧å€ãè¶ãããšäŸå€ã£ãœã
- ã¹ã¿ãã¯ã®åºãã€ãããšãã¯æªå®çŸ©ã£ãœã
- Idriså®è£ ã¯0ãè¿ããŠãHaskellå®è£ ã¯äŸå€
- ååšããªãã©ãã«ã«ãžã£ã³ãããããšããã®ã¯æªå®çŸ©ã£ãœã
- Haskellã¯å®è¡æãšã©ãŒãã€ãŸãååšããªãã©ãã«ã«ãžã£ã³ãããã³ãã³ãã«ããããã£ããšããã§ãšã©ãŒ
- Idrisã¯æ€æ»ãšã©ãŒãã€ãŸãå®éã«ã¯å®è¡ãããªãã³ãã³ãã§ãå®è¡ã«å ¥ãåã«ãšã©ãŒã«ãªã
- outcharãšreadcharã®çŽ°ããªä»æ§ãäžæ
- ããããHaskellãšIdrisãæ°å€<->æåå€æã§ã§ãããã®ã®ã¿æ±ããã
- å®è³ªASCIIã®ã¿ïŒ
- readnumãšreadcharã®EOFã®æ±ããäžæ
- å€åãšã©ãŒãã§ãEOFã¯æ±ããŠã»ãããªâŠã
å ã¿ã«Haskellå®è£ ã¯æå ã«GHCåŠçç³»ããªããŠãIdriså®è£ ã¯ææ°çã®Idrisã³ã³ãã€ã©ã§ã³ã³ãã€ã«ã§ããªãã®ã§ã©ã¡ããã³ã³ãã€ã©äœæã«ã¯äœ¿ã£ãŠãªãã§ãã
ããããšs
ã t
ã n
以å€ã®æåã¯ã³ã¡ã³ãæ±ãã§ç¡èŠãããŸãã
ãšããã§ãç±å¿ãªHaskellããã°ã©ããªãäžèšã®ã³ãã³ãã»ããã«èŠèŠãããããããããŸãããããã¯G-Machineã«ç±æ¥ãããã®ã ããã§ãã
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>Incidentally, for those who are interested in this sort of thing, Whitespace is essentially the G-machine with a weird syntax. You could probably use it as a target for a functional language. I keep thinking I should try that...
â Edwin Brady (@edwinbrady) May 14, 2019
æµç³ã« s
ã t
ã n
ã ãã§ããã°ã©ãã³ã°ããã®ã¯çºçãã®ãªã®ã§ã¢ã»ã³ãã©ãäœããŸãã
çŽæ¥WhitespaceãæžããŠãªãã®ã§ã»ã«ããã¹ãã®ã¬ã®ã¥ã¬ãŒã·ã§ã³ããã¯å€ãããã§ãããã¢ã»ã³ãã©ã®1ã³ãã³ããWhitespaceã®1ã³ãã³ãã«å¯Ÿå¿ãããšããæå³ã§ã¯å®è³ªWhitespaceã§ããã°ã©ãã³ã°ããŠãŸãã
ä»åã®Whitespaceã®ã³ã³ãã€ã©ã®ã¢ã»ã³ããªãœãŒã¹ã®åé éšåã¯ãããªèŠãç®ã§ãã
Flow call 0x00 # main
Flow end
# fn 0x00
# main {
Flow label 0x00
# init start/top of ops
Stack push 0x02
Stack push 0x08
Heap store
Stack push 0x03
Stack push 0x08
Heap store
Flow call 0x10 # parseInstAll
# init start/top of labels
Stack push 0x04
Stack push 0x03
Heap retrieve
Heap store
Stack push 0x05
Stack push 0x03
Heap retrieve
Heap store
Flow call 0xd0 # collectLabelsAndRewrite
# Flow call 0xb0 # dumpOps
# Flow end
# init start/top of mcode
Stack push 0x06
Stack push 0x05
Heap retrieve
Heap store
Stack push 0x07
Stack push 0x05
Heap retrieve
Heap store
# initialize labels
Flow call 0xf0 # asmCode
# reset top of mcode and run asmCode again
Stack push 0x07
Stack push 0x06
Heap retrieve
Heap store
Flow call 0xf0 # asmCode
Flow call 0x130 # dumpELF
Flow return
# }
ã¹ã¿ãã¯ãã·ã³ãšããã€ããã¯ãããŸãããcall
ã ret
ãã³ã¡ã³ããã€ã³ãã³ãã工倫ããããšã§ãããªãã«ãŸãšããªèŠãç®ã§ããã°ã©ãã³ã°ã§ããããã«ãªããŸãã
çµæ§ããªããã£ããªã³ãã³ããå€ãããã®ãŸãŸã¢ã»ã³ãã©ã«ã§ããããªã®ã§ã ãããããŒã¹âæ©æ¢°èªçæã®ã·ã³ãã«ãªæµãã§ãããŸãã ãã ãã©ãã«ã®æ±ããé£ç©ã§ãã ããã°ã©ã ãäžåºŠå šãŠèµ°æ»ããªããšãžã£ã³ãå ã®ã©ãã«ãã©ãã«ãããåãããŸããããäžæŠãã·ã³èªãçæããªããšãã€ããªå ã®ã©ãã«ã®äœçœ®ãåãããŸããã ããããåæ¡ããŠã以äžã®æµãã§ã³ã³ãã€ã«ããŸã
- ããŒã¹
- ããŒãã«ä»®æ³åœä»€ã䞊ã¹ã
- ã©ãã«èµ°æ»ïŒãªããŒã ïŒ
- ã©ãã«ã®åºçŸé ã«ååãæ¯ããã¡ã¢ãªå ã§ãžã£ã³ããšã©ãã«ã®å¯Ÿå¿ããšãã
- ãã·ã³èªä»®çæ
- ã©ãã«ã®äœçœ®ã決ããããã«ãã·ã³èªãçæããããžã£ã³ãå ã¢ãã¬ã¹ã¯ä»®
- ãã·ã³èªæ¬çæ
- 決ãŸã£ãã©ãã«ã®äœçœ®ã«åºããŠæ£ãããã·ã³èªãçæãã
- ELFåºå
- ãã·ã³èªåã«ELFã®ããããã€ããŠåºåãã
é£æ³é åãšãããªããŠèŠããã®ã§ã©ãã«èµ°æ»ã®æ®µã¯ã¡ãã£ãšèŠåŽããŸããã
ãã®ä»ã现ããªç¹ã§ä»æ§ãå€ãã£ãŠããããŸãã
- å€ã¯64bitæŽæ°ãšãã
- ä»»æé·æŽæ°ããã®å€æŽ
- ã©ãã«ã¯2é²æ°ã®æŽæ°ãšããŠããŒã¹ãã
- ããšã§èããã
st
ãšsst
ãåãå€ã«ãªã£ãŠããŸãã®ã§NGã ã£ã
- ããšã§èããã
- ã¹ã¿ãã¯ãåºãã€ãããæªå®çŸ©åäœãšãã
- 確ä¿ããŠãªãã¡ã¢ãªé åã«ããã®ã§å€åSEGV
- æªåæåã®ããŒãã«ã¢ã¯ã»ã¹ãããæªå®çŸ©åäœãšãã
mmap
ã§ç¢ºä¿ããŠãã®ã§0ãè¿ãã®ããªïŒ
readchar
ãoutchar
ã¯ä»»æã®ãªã¯ããããæ±ãããã®ãšãã- ãã€ããªãæ±ãã®ã«å¿ é
- éã«Unicodeã®ã³ãŒããã€ã³ããšãã¯æ±ããªããªã£ã
readchar
ãreadnum
ã¯EOFã«ããã£ããããŒãã«å€ãä¿åããªããã®ãšãã- ãã¡ã€ã«ã®æ«å°ŸãŸã§èªã¿ããã®ã§ãšã©ãŒã ãšå°ã
äž»ã«charã®æ±ãã®åé¡ã§æ¢åã®åŠçç³»ã䜿ããªãã®ã§ãããã«è»¢ãã£ãŠããåŠçç³»ã«ããããåœãŠãŠäœ¿ã£ãŠããŸããã ã©ãã§æŸã£ããèŠããŠãªãã®ãšã確ãã©ã€ã»ã³ã¹ãæèšãããŠããªãã£ãã®ã§ããã¯å ¬éã§ããªããã€ã§ããã ããŒãã¹ãã©ããã«å¿ èŠãªåŠçç³»ãäžã®äžã«ååšããªããšããæ®å¿µãªããšã«ãªã£ãŠããŸããŸããã
äžçªæåã«äœã£ãã®ã¯ELFãããã®åºåã§ããã
Wikipediaããªã³ã«ã»ããŒãå®è·µéçºãã¯ããã¯ãèŠãªãããã£ãŒã«ããåããŠãããŸãããããŸããŸãã€ããã£ãã§ãã Program Headerã§æ©æ¢°èªã ããã¡ã¢ãªã«ããŒãããŠå®è¡ããããšãããã©ãããŠãåããªããŠãæ £äŸã«åŸã£ãŠELFãã¡ã€ã«å šäœãããŒããããåããããšããããåãããªããã©ãããããåããç¶æ ã«ãªããŸãããã«ãŒãŽã«ã«ãã§ããã
ELFãããããããŠããªããšãEXEãäœããã®ã粟äžæ¯ã ã£ãã®ã§libcã ãšãã®ãªã³ã¯ãå¿ èŠãªãã®ã¯äœ¿ãããã«ãããŸããã§ãããã³ã³ãã€ã©ã¯é 匵ã£ãŠãã·ã³èªã䞊ã¹ãŠããæ¹éã§ãããŸãã
ELFãäœããããã«ãªã£ãã次ã¯ããŒã¹ã§ãã ããã¯ãŸããææ £ããŠãã®ã§ç¹çããããšã¯ãªãã§ãã çéã®äººãªãWhitespaceã®ææ³ãäžç¥ããã°ãããåçãããªãŒãããã³ãåæã«çæããããšæãã®ã§ãã®ãŸãŸå®è£ ããã ãã§ãã
ããŒã¹ã®ã³ãŒããæžããããäžæŠããŒã¹ããã³ãã³ãããã®ãŸãŸ push
ãšã readchar
ãšãã®æååã§åºåããããã«ããŸãããããã§ããŒãµïŒãšèªäœã¢ã»ã³ãã©ïŒã®ãããã°ãããŸãã
ããŒã¿æ§é ãšãããããã®ããªãã®ã§ã¡ã¢ãªã®äœçªå°ãäœã«äœ¿ããã¯äºåã«èšç»ããªããšç Žç¶»ããŸãã ã³ã³ãã€ã©ã®ã³ãŒãã®ã³ã¡ã³ãããæç²ãããšã以äžã®ãããªã¬ã€ã¢ãŠãã«ããŸããã
# Heap layout
# 0/1 1/1
# +----------+--------------------+-
# | readchar | parse number/label |
# +----------+--------------------+-
# 2/1 3/1 4/1 5/1 6/1 7/1
# -+--------------+------------+-----------------+---------------+----------------+--------------+-
# | start of ops | top of ops | start of labels | top of labels | start of mcode | top of mcode |
# -+--------------+------------+-----------------+---------------+----------------+--------------+-
# 8/l 8+l/m 8+l+m/n
# -+------------+--------+--------------+
# | parsed ops | labels | machine code |
# -+------------+--------+--------------+
# where ops forms | op | arg |
# ops:
# 0x00 push
# 0x01 dup
# 0x02 copy
# 0x03 swap
# 0x04 discard
# 0x05 slide
# 0x10 add
# 0x11 sub
# 0x12 mul
# 0x13 div
# 0x14 mod
# 0x20 store
# 0x21 retrieve
# 0x30 label
# 0x31 call
# 0x32 jump
# 0x33 jz
# 0x34 jneg
# 0x35 return
# 0x36 end
# 0x40 outchar
# 0x41 outnumber
# 0x42 readchar
# 0x43 readnumber
0, 1çªå°ã¯äœæ¥çšããã以éã«å¯å€é·ããŒã¿ãžã®ãã€ã³ã¿ãå¯å€é·ããŒã¿ã®å®äœã䞊ã³ãŸãã å¯å€é·ããŒã¿ã¯ããŒã¹ããã³ãŒããããã°ã©ã äžã«å«ãŸããã©ãã«äžèŠ§ãæ©æ¢°èªã®3ã€ããããŸãã
ä»åã®äœæ¥ã¯ããŒã¿ã¬ã€ã¢ãŠããæ£ããèšèšããã®ãäžçªã®é¬Œéã§ããã ããã決ãŸã£ãããšã¯ãããšãããªãé²ã¿ãŸããã ãŸããããŒã¿ã¬ã€ã¢ãŠãã決ãããšãã«å®è£ ã®ããšãèããªããšãããªããããšããã®ããããŸãã
ããã°ã©ã äžã§æ±ãã©ãã«ã¯ã°ããŒãã«ãªåå空éãããªãã®ã§å·¥å€«ããªããšãããã£ã³ã°ããŠç Žç¶»ããŸãã
é¢æ°ã®ã©ãã«ã«ã¯ 0x10
ã 0x20
⊠ãš16ã®åæ°ãå²ãåœãŠãé¢æ°å
ã§äž1æ¡ã1ã¥ã€ã€ã³ã¯ãªã¡ã³ãããŠäœ¿ã£ãŠãŸããã
ããã€ããé¢æ°å
ã§ã®åå²ãå€ããŠ16å以äžã®ã©ãã«ã䜿ã£ããã®ããããŸããããããã¯æ¬¡ä»¥éã®é¢æ°ã®ã©ãã«ããããããšã§è§£æ±ºããŸããã
æ¢ã«å°ã説æããŸãããã©ãã«ã®æ±ããæã«äœããŸããã
ãŸããã©ãã«ã¯ä»»æé·ã® s
ãš t
ã®æååãšããŠäžããããŸãã
ããã64bitã®ç¬Šå·ãªãæŽæ°ã«ãšããŠããŒã¹ããŸããããã ãšå®ã¯æ
å ±ã«æ¬ æãããã®ã¯æ¢è¿°ã®ãšããã§ãããäžæŠå¿ããŸãããã
次ã«ã©ãã«ãåºçŸé ã®ã€ã³ããã¯ã¹ã§ãªããŒã ããŸããããã¯labelãjumpãªã©å šãŠã®ã©ãã«ãæ±ãã³ãã³ãããæŸããŸãã äŸãã°ä»¥äžã®ããã°ã©ã ã§ããã°
Flow call 0x00
Flow end
Flow label 0x00
Stack push 0x02
Stack push 0x08
Heap store
Stack push 0x03
Stack push 0x08
Heap store
Flow call 0x10
ã©ãã«ãåºçŸé ã«äžŠã¹ããšãããªããŸãã
0x00
0x00
0x10
ããã¯ãããªããŒã ãããŸãã
0x00 -> 0
0x10 -> 1
ãããŠã©ãã«äžèŠ§ã®ãšããã«ãèšé²ããŸãã
0 1
+------+------+--
| 0x00 | 0x10 |
+------+------+--
ããããããšã§ããã©ãã«äžèŠ§å ã®ã€ã³ããã¯ã¹ã = ããªããŒã ãããã©ãã«ãã«ã§ããŸãã
ããšã¯ã©ãã«ãã¿ã€ãããã
- ã©ãã«äžèŠ§ã«ã©ãã«ããã â ãã®ã€ã³ããã¯ã¹ã«ãªããŒã
- ã©ãã«äžèŠ§ã«ã©ãã«ããªã â ã©ãã«äžèŠ§ã«ã©ãã«ãè¿œå ãããã®ã€ã³ããã¯ã¹ã«ãªããŒã
ãšããåŠçãç¹°ãè¿ãã°ã©ãã«ã®äžåŠçã¯å®äºã§ãã
äžåºŠäžåŠçãçµããã°ã©ãã«äžèŠ§å ã®ããŒã¿ã¯äžèŠã«ãªãã®ã§ãã·ã³èªå ã®ããžã·ã§ã³ã®ç¢ºå®ã«åå©çšããŸãã labelã³ãã³ãã®ãã·ã³èªçææã«ãçŸåšã®ãã·ã³èªã®topïŒèŠã¯ãã·ã³èªå ã§ã®ããžã·ã§ã³ïŒãã©ãã«äžèŠ§ã®èªåã®ã©ãã«ã®ã»ã«ã«èšé²ããŸãã ãããŠãžã£ã³ãç³»ã³ãã³ãã®ãã·ã³èªçææã«ããããã©ãã«ã®ãã·ã³èªäœçœ®ãèªã¿åã£ãŠãçŸåšã®ãã·ã³èªtopãšåŒãç®ããŠçžå¯Ÿã¢ãã¬ã¹ãç®åºããŸãã ãžã£ã³ãç³»ã³ãã³ãã®æ¹ãã©ãã«ããåŸã«ããããšãããã®ã§ãã®èµ°æ»ãäºåããã°ç¢ºå®ã«ã¢ãã¬ã¹ãèšç®ã§ããããšã«ãªããŸãã ãããä»®çæãæ¬çæãšåŒãã§ãããã®ã§ãã
ã»ãšãã©ã®ã³ãã³ãã¯ã¢ã»ã³ãã©æ°åœä»€ã§è¡šçŸå¯èœãªã®ã§ããŸãå°ããŸããã§ããã ãã ããå ã«ã©ã³ã¿ã€ã ãèšèšããŠããå¿ èŠããããŸãã
ä»åã¯Linuxã§åãã°ãããã®æ°æã¡ã ã£ãã®ã§éã«å®è£ ããŸãã å¿ èŠãããªã®ã¯Whitespaceã§äœ¿ãã¹ã¿ãã¯ãšããŒããã¹ã¿ãã¯ã®ããããæããã€ã³ã¿ãšããŒãã®ããŒã¹ãæããã€ã³ã¿ãã³ãŒã«ã¹ã¿ãã¯ã§ããã³ã³ãã€ã©ã®ã³ã¡ã³ãããæç²ãããšããããããããèšèšã§ãã
## runtime architecture
# runtime heap map
#
# +------------+-------------+- -+---------------+
# | ws heap -> | ws stack -> | ... | <- call stack |
# +------------+-------------+- -+---------------+
# registers
# rbp ... base of ws heap
# rbx ... top of ws stack
# rsp ... ordinal rsp.
# and some registers are used to hold temporal values
# values
# all values are 64-bit
ã³ãŒã«ã¹ã¿ãã¯ãšrspã¯æ®éã®ãã€ãã®ãŸãŸãWhitespaceã®ããŒããšã¹ã¿ãã¯ã¯mmapã§ãããã確ä¿ããŸãã
ã¹ã¿ãã¯ãšããŒããæããã€ã³ã¿ã« rbx
ãš rbp
ãéžãã ã®ã¯ã·ã¹ãã ã³ãŒã«ãåŒãã§ãä¿åãããæ±çšã¬ãžã¹ã¿ã§ãåœä»€ã«ãšã³ã³ãŒããããšãã«çããã®ã ããã§ãã
ã¹ã¿ãã¯ã®ãã€ã³ã¿ã« rbp
ã䜿ããã£ãŠçªã£èŸŒãŸãããããããŸãããã³ãŒã«ã¹ã¿ãã¯ãšã¯éåãã«ã¹ã¿ãã¯ã䌞ã³ãèšèšã«ããŠããŸã£ãã®ã§æ°ã«ããã«ããŒãçšã«äœ¿ã£ãŠããŸãã
mmapãreadãwriteãexitã®ã·ã¹ãã ã³ãŒã«çªå·ã¯ ãã¡ãã®ãŸãšãããæŸããŸãããã©ã®ã¬ãžã¹ã¿ã«ã©ã®å€ãå ¥ããã°ããã®ããèŒã£ãŠãã®ã§åãããããã£ãã§ããmmapã«æž¡ããã©ã°ããããã¯ã·ã§ã³ãã©ã°ãªã©ã¯Linuxã®ããããã¡ã€ã«ããèªã¿ãšããŸããã
ãããŸãé£ããããšã¯ãã£ãŠãªãã§ããäŸãã°pushã³ãã³ããªãããã§ãã
# mov QWORD PTR [rbx], arg
# 48 c7 03 xx xx xx xx
Stack push 0x48
Stack push 0xc7
Stack push 0x03
Stack copy 3
Heap retrieve
Flow call 0x110 # decodeLE
Stack push 7
Flow call 0x120 # storeMCode
# add rbx, 0x08
# 48 83 c3 08
Stack push 0x48
Stack push 0x83
Stack push 0xc3
Stack push 0x08
Stack push 4
Flow call 0x120 # storeMCode
ãããreturnã³ãã³ããšãã«ãªããšãã£ãšç°¡åã§ããã
# ret
# c3
Stack push 0xc3
Stack push 1
Flow call 0x120 # storeMCode
ãã·ã³èªã¯https://godbolt.orgã«ã¢ã»ã³ãã©ãæã£ãŠååŸããŸããã
ããã§èŠåŽããã®ã readnum
ãš writenum
ã§ãã
ä»ã¯æ°åœä»€ã§æžãã®ã«ãããã¯æ°ååœä»€ãããŸããé 匵ã£ãŠå®è£
ããŸããã
æ°ååœä»€ã§ããããã§ããµãã£ãŠããŠã笊å·ã®æ±ãã¯æªå®è£
ã§ãã
ç¹æ®µã¢ã»ã³ãã©ã®ãããã°ç°å¢ã¯çšæããªãã£ãã®ã§Whitespaceã³ã³ãã€ã©ãåãããŠæåãå€ã ã£ãããã€ããªããããã°ããŠâŠãšããããã«ããŸãããã€ããã§ããã
ãŸããŸã倧å€ã ã£ãã®ã§è²ã æãåºããŸãã
å ¬åŒãµã€ãã«ç¹ãããªããŠãæ£ããæ å ±ãéããããŸããã§ãããç¹ã«èŠåŽããã®ãslideã³ãã³ãã§ãã ç§ãæå ã§äœ¿ã£ãåŠçç³»ãäœè ã«ããIdriså®è£ ããã°ã£ãŠããŠãWebArchiveãããªãªãžãã«ã®å®è£ ãæãåºããŠããããç解ã§ããŸããã
ãLinuxã§åãæå°ã®ELFããšããããã°äœ¿ãããã£ããã§ããïŒãããŸãç±å¿ã«æ€çŽ¢ããªãã£ãã®ããã£ãŠïŒèŠä»ããããè©Šè¡é¯èª€ããªããçæããŠãããŸããã
ãã€ããªãšãã£ã¿ã§éããŠ1ãã€ããã€æå·®ã確èªããŠãããã°ããŠãããŸããã æ¢åã®ELFãããã€ãçºããã®ã§ããããã°ã©ã ãããŒãããã¢ãã¬ã¹ãæ§ã ã§é¢çœãã£ãã§ãã
ä»åçæããã®ã¯EXEãªã®ãšãåŽååæžã®ããã«ã»ã¯ã·ã§ã³ããããçæããªãã£ãã®ã§ã·ã³ãã«ãªãã§ãããã°ããå¿ èŠããããŸãããã·ã³ãã«ã«ã€ããã§ããã
ãšããã§gdbã§æ©æ¢°èªããããã°ããTipsãå°ãåŸãããŸããã
layout asm
â ä»å®è¡ããŠããã¢ã»ã³ãã©ã衚瀺ããstarti
â ããã°ã©ã ãå®è¡ããã¢ã»ã³ãã©ã®äžçªæåã®åœä»€ã§breakããstepi
â ã¢ã»ã³ãã©1åœä»€å®è¡ããinfo registers
â ã¬ãžã¹ã¿ã®äžèº«ã衚瀺ãã
æçµçã« info registers
ãæ¯åæã€ã®ã¯ãã£ãŠãããªãã®ã§gdb dashboardã䜿ããŸããã
çŸè±¡ãšããŠã¯åããããããŠãELFã®æå®ãããã¡ã€ã«ãµã€ãºãè¶ããç®æã«ã¢ã¯ã»ã¹ããŠããŸãã ãããçŸè±¡ãåãã£ãŠãåå ã¯å šç¶åãããŸããã§ããã ELFã®çæã³ãŒãã®åé¡ãçã£ãã®ã§ãããELFçæãšã¯é¢ä¿ãªããã·ã³èªã®é·ãããããã°åºåããŠã¿ããæ£ããããªã®ã§ãæäžãã§ããã çµå±ããã·ã³èªãµã€ãºãé©åœã«æ°Žå¢ãããŠããŸãããŸããã
ãããä»ã«ãªã£ãŠããèãããã¡ã¢ãªã«ããŒããããšãã«ELFãã¡ã€ã«ã®ãããããšããŒãããŠãã®ã§ããã§100byteãããæ³å®ããé·ããªã£ãŠãã®ãããããŸãã ãšãªããšãæ«å°Ÿã®æ°ã³ãã³ãïŒoutcharãããã®ã§ãã·ã³èªã«ãããšé·ãïŒ+ æåŸã®exitã®åŒã³åºãã§100byteããããããããªã®ã§çŽåŸã§ããã ããšã§ä¿®æ£ããã
whitespaceã§æžãããã³ã³ãã€ã©ã第0äžä»£ãããã䜿ã£ãŠèªèº«ãã³ã³ãã€ã«ãããã®ã第1äžä»£ã第1äžä»£ã䜿ã£ãŠwhitespaceã§æžãããã³ã³ãã€ã©ãã³ã³ãã€ã«ããã®ã第2äžä»£ãšåŒã¶ããšã«ããŸãã å®å šãªã»ã«ããã¹ãã³ã³ãã€ã©ã§ããã°ç¬¬1äžä»£ãšç¬¬2äžä»£ã¯ãã€ããªã¬ãã«ã§å®å šäžèŽããŸãã
第1äžä»£ã³ã³ãã€ã©ã¯ãªããšãªãåããŠããã©ã第2äžä»£ã³ã³ãã€ã©ãçæãããšãã€ããªã¬ãã«ã§äžèŽããªããå€ãªæåããããšãã®ã話ã çŽæ¥æžããã³ãŒãããã°ã£ãŠããèš³ã§ã¯ãªãã®ã§ããªãå³ãããã®ããããŸãã第2äžä»£ã®æåãèŠãŠããã°ã£ãŠããããªç¬¬1äžä»£ã®ã³ã³ãã€ã©ã®æªãããšããã«æ€èšãã€ããŠãããã®éšåãçæãã第0äžä»£ã®ã³ã³ãã€ã©ã®è©²åœç®æãè¡çŒã«ãªã£ãŠãããã°ããŸããæ£çŽãèªåãä»äœããããã°ããŠããã®ãåãããªããªããŸãã
gdbã§ç¬¬1äžä»£ããããã°ã§ãããããã£ããã§ããå è¿°ã®éãã·ã³ãã«ããªãã®ãšãã³ã³ãã€ã©ã¯å€§ãããŠãã€ããªå ã§ãã°ã£ãŠãç®æãåãã£ããšããŠããœãŒã¹ã³ãŒããšã®å¯Ÿå¿ãäžã ãšããªãã®ã§é£èªããŸããã
çµå±ããã°ãåçŸããã³ãŒããã©ãã©ãçž®ããŠãã£ãŠå°ããªãã€ããªã§ãããã°ããŸããã
å ã¿ã«ãã°ã£ãŠããã®ã¯è² ã®å€ã®ãªãã©ã«ã®ããŒã¹ã§ããã ã³ã³ãã€ã©å ã§ã¯1ç®æããè² ã®å€ã䜿ã£ãŠããã®ã§ãããããåããã©ããŸã«å€ãªã³ãŒããé£ããããšãã°ãããšããæåã«ãªããŸãããã€ããã
Whitespaceã§ã»ã«ããã¹ãã³ã³ãã€ã©ãäœãããšããfoolãªããšãæãä»ããã®ã¯å ã«åŒçšããEdwin Bradyã®ãã€ãŒããèŠããšãã§ããã æåã¯Whitespaceã«ã³ã³ãã€ã«ããé¢æ°åèšèªã§ãäœããããšæã£ãŠãã®ã§ãããè³å ã§è²ã ããããåããŠããéã«ãšã€ããªã«ããŒã«ã«Whitespaceã®ã»ã«ããã¹ãã³ã³ãã€ã©ãäœããšããçºæ³ã«è³ããŸããã
èšç»ã¯éååãããã£ããã®ã®ãå®éã«åãæãã£ãã®ã¯3æäžã ã£ãã®ã§æéã足ãããæ絊ã2æ¥äœ¿ã£ãŠãããã3æ31æ¥ã®22æãšããã®ãªã®ãªã®æéã«å®æããŸããã æ絊ãŸã§äœ¿ã£ãŠäœããŠããã§ãããããæãªããfoolã ãªãšæããŸãã
ä»å¹Žã¯ããçµãããŸãããæ¥å¹Žã¯ã¿ãªãããfoolãªããšãã£ãŠãããŸãããã
ä»åã®ã³ã³ãã€ã©ã®ã¢ã»ã³ãã©ãšã¢ã»ã³ããªã®ã³ãŒãã¯ãã¡ãã«çœ®ããŠãããŸããã©ã€ã»ã³ã¹ã¯GPLv2ãšããŸãã
https://gist.github.com/KeenS/6081b0c802a4e575ddbacb1930680870