code format
This commit is contained in:
parent
224520740b
commit
4efdae3a4f
@ -1,19 +1,31 @@
|
|||||||
module Header exposing (header)
|
module Header exposing (header)
|
||||||
|
|
||||||
import Html.Styled exposing (..)
|
import Html.Styled exposing (..)
|
||||||
import Html.Styled.Attributes exposing (style, target, src, class)
|
import Html.Styled.Attributes exposing (class, src, style, target)
|
||||||
|
|
||||||
import Route
|
|
||||||
import Link exposing (Link)
|
import Link exposing (Link)
|
||||||
|
import Route
|
||||||
|
|
||||||
header = p [ style "display" "flex", style "flex-direction" "row", style "justify-content" "flex-start" ]
|
|
||||||
|
header =
|
||||||
|
p [ style "display" "flex", style "flex-direction" "row", style "justify-content" "flex-start" ]
|
||||||
[ p [ style "margin-right" "1rem" ] [ home ]
|
[ p [ style "margin-right" "1rem" ] [ home ]
|
||||||
, p [ style "margin-right" "1rem" ] [ blog ]
|
, p [ style "margin-right" "1rem" ] [ blog ]
|
||||||
, p [ style "margin-right" "1rem" ] [ book ]
|
, p [ style "margin-right" "1rem" ] [ book ]
|
||||||
, p [ style "margin-right" "1rem" ] [ cv ]
|
, p [ style "margin-right" "1rem" ] [ cv ]
|
||||||
]
|
]
|
||||||
|
|
||||||
home = Link.link (Link.internal (Route.Index)) [] [ text "Home" ]
|
|
||||||
blog = Link.link (Link.internal (Route.Blog__Slug_ { slug = "" })) [] [ text "Blog" ]
|
home =
|
||||||
book = Link.link (Link.internal (Route.Book)) [] [ text "Book" ]
|
Link.link (Link.internal Route.Index) [] [ text "Home" ]
|
||||||
cv = Link.link (Link.external "/cv.pdf") [ target "_blank" ] [ text "CV" ]
|
|
||||||
|
|
||||||
|
blog =
|
||||||
|
Link.link (Link.internal (Route.Blog__Slug_ { slug = "" })) [] [ text "Blog" ]
|
||||||
|
|
||||||
|
|
||||||
|
book =
|
||||||
|
Link.link (Link.internal Route.Book) [] [ text "Book" ]
|
||||||
|
|
||||||
|
|
||||||
|
cv =
|
||||||
|
Link.link (Link.external "/cv.pdf") [ target "_blank" ] [ text "CV" ]
|
||||||
|
@ -7,23 +7,21 @@ import FatalError exposing (FatalError)
|
|||||||
import Head
|
import Head
|
||||||
import Head.Seo as Seo
|
import Head.Seo as Seo
|
||||||
import Html.Styled exposing (..)
|
import Html.Styled exposing (..)
|
||||||
import Html.Styled.Attributes exposing (style, class)
|
import Html.Styled.Attributes exposing (class, style)
|
||||||
import Json.Decode as Decode exposing (Decoder)
|
import Json.Decode as Decode exposing (Decoder)
|
||||||
import Json.Decode.Extra
|
import Json.Decode.Extra
|
||||||
|
import Link
|
||||||
|
import Markdown.Block
|
||||||
|
import Markdown.Renderer
|
||||||
|
import MarkdownCodec
|
||||||
import Pages.Url
|
import Pages.Url
|
||||||
import PagesMsg exposing (PagesMsg)
|
import PagesMsg exposing (PagesMsg)
|
||||||
import Route exposing (Route)
|
import Route exposing (Route)
|
||||||
import RouteBuilder exposing (App, StatelessRoute)
|
import RouteBuilder exposing (App, StatelessRoute)
|
||||||
import Shared
|
import Shared
|
||||||
import View exposing (View)
|
|
||||||
import Link
|
|
||||||
|
|
||||||
|
|
||||||
import Markdown.Block
|
|
||||||
import Markdown.Renderer
|
|
||||||
import MarkdownCodec
|
|
||||||
import TailwindMarkdownRenderer
|
|
||||||
import Tailwind.Utilities as Tw
|
import Tailwind.Utilities as Tw
|
||||||
|
import TailwindMarkdownRenderer
|
||||||
|
import View exposing (View)
|
||||||
|
|
||||||
|
|
||||||
type alias Model =
|
type alias Model =
|
||||||
@ -33,9 +31,11 @@ type alias Model =
|
|||||||
type alias Msg =
|
type alias Msg =
|
||||||
()
|
()
|
||||||
|
|
||||||
|
|
||||||
type alias RouteParams =
|
type alias RouteParams =
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
route : StatelessRoute RouteParams Data ActionData
|
route : StatelessRoute RouteParams Data ActionData
|
||||||
route =
|
route =
|
||||||
RouteBuilder.single
|
RouteBuilder.single
|
||||||
@ -46,7 +46,8 @@ route =
|
|||||||
|
|
||||||
|
|
||||||
type alias Data =
|
type alias Data =
|
||||||
List (Route, Article.ArticleMetadata)
|
List ( Route, Article.ArticleMetadata )
|
||||||
|
|
||||||
|
|
||||||
type alias ActionData =
|
type alias ActionData =
|
||||||
{}
|
{}
|
||||||
@ -57,6 +58,7 @@ data =
|
|||||||
Article.blogAllMetadata
|
Article.blogAllMetadata
|
||||||
|> BackendTask.allowFatal
|
|> BackendTask.allowFatal
|
||||||
|
|
||||||
|
|
||||||
head :
|
head :
|
||||||
App Data ActionData RouteParams
|
App Data ActionData RouteParams
|
||||||
-> List Head.Tag
|
-> List Head.Tag
|
||||||
@ -91,16 +93,19 @@ view app shared =
|
|||||||
, text " "
|
, text " "
|
||||||
, Link.link (Link.internal (Route.Osx__Slug_ { slug = "" })) [] [ text "series" ]
|
, Link.link (Link.internal (Route.Osx__Slug_ { slug = "" })) [] [ text "series" ]
|
||||||
, text " "
|
, text " "
|
||||||
, text "about the Mach-O binary format, used in Apple devices." ]
|
, text "about the Mach-O binary format, used in Apple devices."
|
||||||
|
]
|
||||||
, div [] (app.data |> List.map renderBlogItem)
|
, div [] (app.data |> List.map renderBlogItem)
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
renderBlogItem : (Route, Article.ArticleMetadata) -> Html msg
|
|
||||||
renderBlogItem (route_, article) =
|
renderBlogItem : ( Route, Article.ArticleMetadata ) -> Html msg
|
||||||
|
renderBlogItem ( route_, article ) =
|
||||||
div []
|
div []
|
||||||
[ Link.link (Link.internal route_) [ style "text-decoration" "none" ]
|
[ Link.link (Link.internal route_)
|
||||||
|
[ style "text-decoration" "none" ]
|
||||||
[ ul
|
[ ul
|
||||||
[]
|
[]
|
||||||
[ li []
|
[ li []
|
||||||
@ -109,5 +114,6 @@ renderBlogItem (route_, article) =
|
|||||||
]
|
]
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
|
||||||
-- , span [ class "marginnote", style "margin-right" "0" ] [ text (Date.toIsoString article.published) ]
|
-- , span [ class "marginnote", style "margin-right" "0" ] [ text (Date.toIsoString article.published) ]
|
||||||
]
|
]
|
||||||
|
@ -7,23 +7,21 @@ import FatalError exposing (FatalError)
|
|||||||
import Head
|
import Head
|
||||||
import Head.Seo as Seo
|
import Head.Seo as Seo
|
||||||
import Html.Styled exposing (..)
|
import Html.Styled exposing (..)
|
||||||
import Html.Styled.Attributes exposing (style, class)
|
import Html.Styled.Attributes exposing (class, style)
|
||||||
import Link exposing (Link)
|
|
||||||
import Json.Decode as Decode exposing (Decoder)
|
import Json.Decode as Decode exposing (Decoder)
|
||||||
import Json.Decode.Extra
|
import Json.Decode.Extra
|
||||||
|
import Link exposing (Link)
|
||||||
|
import Markdown.Block
|
||||||
|
import Markdown.Renderer
|
||||||
|
import MarkdownCodec
|
||||||
import Pages.Url
|
import Pages.Url
|
||||||
import PagesMsg exposing (PagesMsg)
|
import PagesMsg exposing (PagesMsg)
|
||||||
import Route
|
import Route
|
||||||
import RouteBuilder exposing (App, StatelessRoute)
|
import RouteBuilder exposing (App, StatelessRoute)
|
||||||
import Shared
|
import Shared
|
||||||
import View exposing (View)
|
|
||||||
|
|
||||||
|
|
||||||
import Markdown.Block
|
|
||||||
import Markdown.Renderer
|
|
||||||
import MarkdownCodec
|
|
||||||
import TailwindMarkdownRenderer
|
|
||||||
import Tailwind.Utilities as Tw
|
import Tailwind.Utilities as Tw
|
||||||
|
import TailwindMarkdownRenderer
|
||||||
|
import View exposing (View)
|
||||||
|
|
||||||
|
|
||||||
type alias Model =
|
type alias Model =
|
||||||
@ -64,6 +62,7 @@ type alias Data =
|
|||||||
, body : List Markdown.Block.Block
|
, body : List Markdown.Block.Block
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
type alias ActionData =
|
type alias ActionData =
|
||||||
{}
|
{}
|
||||||
|
|
||||||
@ -81,6 +80,7 @@ type alias ArticleMetadata =
|
|||||||
, subtitle : String
|
, subtitle : String
|
||||||
, description : String
|
, description : String
|
||||||
, published : Date
|
, published : Date
|
||||||
|
|
||||||
-- , image : Pages.Url.Url
|
-- , image : Pages.Url.Url
|
||||||
, draft : Bool
|
, draft : Bool
|
||||||
}
|
}
|
||||||
@ -111,6 +111,7 @@ frontmatterDecoder =
|
|||||||
|> Decode.map (Maybe.withDefault False)
|
|> Decode.map (Maybe.withDefault False)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
head :
|
head :
|
||||||
App Data ActionData RouteParams
|
App Data ActionData RouteParams
|
||||||
-> List Head.Tag
|
-> List Head.Tag
|
||||||
@ -136,7 +137,9 @@ view :
|
|||||||
-> Shared.Model
|
-> Shared.Model
|
||||||
-> View (PagesMsg Msg)
|
-> View (PagesMsg Msg)
|
||||||
view app shared =
|
view app shared =
|
||||||
let rendered = (app.data.body |> Markdown.Renderer.render TailwindMarkdownRenderer.renderer) |> Result.withDefault []
|
let
|
||||||
|
rendered =
|
||||||
|
(app.data.body |> Markdown.Renderer.render TailwindMarkdownRenderer.renderer) |> Result.withDefault []
|
||||||
in
|
in
|
||||||
{ title = app.data.metadata.title
|
{ title = app.data.metadata.title
|
||||||
, body =
|
, body =
|
||||||
|
@ -10,20 +10,18 @@ import Html.Styled exposing (..)
|
|||||||
import Html.Styled.Attributes as Attributes
|
import Html.Styled.Attributes as Attributes
|
||||||
import Json.Decode as Decode exposing (Decoder)
|
import Json.Decode as Decode exposing (Decoder)
|
||||||
import Json.Decode.Extra
|
import Json.Decode.Extra
|
||||||
|
import Link
|
||||||
|
import Markdown.Block
|
||||||
|
import Markdown.Renderer
|
||||||
|
import MarkdownCodec
|
||||||
import Pages.Url
|
import Pages.Url
|
||||||
import PagesMsg exposing (PagesMsg)
|
import PagesMsg exposing (PagesMsg)
|
||||||
import Route exposing (Route)
|
import Route exposing (Route)
|
||||||
import RouteBuilder exposing (App, StatelessRoute)
|
import RouteBuilder exposing (App, StatelessRoute)
|
||||||
import Shared
|
import Shared
|
||||||
import View exposing (View)
|
|
||||||
import Link
|
|
||||||
|
|
||||||
|
|
||||||
import Markdown.Block
|
|
||||||
import Markdown.Renderer
|
|
||||||
import MarkdownCodec
|
|
||||||
import TailwindMarkdownRenderer
|
|
||||||
import Tailwind.Utilities as Tw
|
import Tailwind.Utilities as Tw
|
||||||
|
import TailwindMarkdownRenderer
|
||||||
|
import View exposing (View)
|
||||||
|
|
||||||
|
|
||||||
type alias Model =
|
type alias Model =
|
||||||
@ -33,9 +31,11 @@ type alias Model =
|
|||||||
type alias Msg =
|
type alias Msg =
|
||||||
()
|
()
|
||||||
|
|
||||||
|
|
||||||
type alias RouteParams =
|
type alias RouteParams =
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
route : StatelessRoute RouteParams Data ActionData
|
route : StatelessRoute RouteParams Data ActionData
|
||||||
route =
|
route =
|
||||||
RouteBuilder.single
|
RouteBuilder.single
|
||||||
@ -46,7 +46,8 @@ route =
|
|||||||
|
|
||||||
|
|
||||||
type alias Data =
|
type alias Data =
|
||||||
List (Route, Article.ArticleMetadata)
|
List ( Route, Article.ArticleMetadata )
|
||||||
|
|
||||||
|
|
||||||
type alias ActionData =
|
type alias ActionData =
|
||||||
{}
|
{}
|
||||||
@ -57,6 +58,7 @@ data =
|
|||||||
Article.osxAllMetadata
|
Article.osxAllMetadata
|
||||||
|> BackendTask.allowFatal
|
|> BackendTask.allowFatal
|
||||||
|
|
||||||
|
|
||||||
head :
|
head :
|
||||||
App Data ActionData RouteParams
|
App Data ActionData RouteParams
|
||||||
-> List Head.Tag
|
-> List Head.Tag
|
||||||
@ -218,4 +220,5 @@ view app shared =
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
linkexternal src title = Link.link (Link.external src) [Attributes.target "_blank"] [text title]
|
linkexternal src title =
|
||||||
|
Link.link (Link.external src) [ Attributes.target "_blank" ] [ text title ]
|
||||||
|
@ -5,14 +5,14 @@ import FatalError exposing (FatalError)
|
|||||||
import Head
|
import Head
|
||||||
import Head.Seo as Seo
|
import Head.Seo as Seo
|
||||||
import Html.Styled exposing (..)
|
import Html.Styled exposing (..)
|
||||||
import Html.Styled.Attributes exposing (style, target, src, class)
|
import Html.Styled.Attributes exposing (class, src, style, target)
|
||||||
import Link exposing (Link)
|
import Link exposing (Link)
|
||||||
import Pages.Url
|
import Pages.Url
|
||||||
import PagesMsg exposing (PagesMsg)
|
import PagesMsg exposing (PagesMsg)
|
||||||
import UrlPath
|
|
||||||
import Route
|
import Route
|
||||||
import RouteBuilder exposing (App, StatelessRoute)
|
import RouteBuilder exposing (App, StatelessRoute)
|
||||||
import Shared
|
import Shared
|
||||||
|
import UrlPath
|
||||||
import View exposing (View)
|
import View exposing (View)
|
||||||
|
|
||||||
|
|
||||||
@ -77,18 +77,19 @@ withSpacing : (List (Html msg) -> Html msg) -> List (Html msg) -> Html msg
|
|||||||
withSpacing element =
|
withSpacing element =
|
||||||
List.intersperse (text " ") >> element
|
List.intersperse (text " ") >> element
|
||||||
|
|
||||||
|
|
||||||
view :
|
view :
|
||||||
App Data ActionData RouteParams
|
App Data ActionData RouteParams
|
||||||
-> Shared.Model
|
-> Shared.Model
|
||||||
-> View (PagesMsg Msg)
|
-> View (PagesMsg Msg)
|
||||||
view app shared =
|
view app shared =
|
||||||
{ title = "nganhkhoa"
|
{ title = "nganhkhoa"
|
||||||
, body = [ article [ class "paperlike" ]
|
, body =
|
||||||
|
[ article [ class "paperlike" ]
|
||||||
[ -- header
|
[ -- header
|
||||||
h1 [] [ text "Me" ]
|
h1 [] [ text "Me" ]
|
||||||
, section []
|
, section []
|
||||||
[
|
[ p []
|
||||||
p []
|
|
||||||
[ text "I am a Security Engineer. My expertise lies in many parts of binary and program analysis. In the past, I have done works on many technical aspect. I believe that most complex parts of Computer Science can be broken down into bytes and bits."
|
[ text "I am a Security Engineer. My expertise lies in many parts of binary and program analysis. In the past, I have done works on many technical aspect. I believe that most complex parts of Computer Science can be broken down into bytes and bits."
|
||||||
, span [ class "marginnote" ] [ img [ src "/nganhkhoa.png" ] [] ]
|
, span [ class "marginnote" ] [ img [ src "/nganhkhoa.png" ] [] ]
|
||||||
]
|
]
|
||||||
@ -96,26 +97,28 @@ view app shared =
|
|||||||
[ text "I also enjoy deep research. I have done a few research deeply on memory forensics and binary formats. I write papers about my research, but as an unexperienced researcher, I am still struggling to get them published."
|
[ text "I also enjoy deep research. I have done a few research deeply on memory forensics and binary formats. I write papers about my research, but as an unexperienced researcher, I am still struggling to get them published."
|
||||||
]
|
]
|
||||||
, p []
|
, p []
|
||||||
[ text "I currently work at", text " "
|
[ text "I currently work at"
|
||||||
|
, text " "
|
||||||
, quicklinks "verichains" "Verichains"
|
, quicklinks "verichains" "Verichains"
|
||||||
, label [ class "sidenote-number" ] []
|
, label [ class "sidenote-number" ] []
|
||||||
, span [ class "sidenote" ] [ text "A security company with renowned reputation." ]
|
, span [ class "sidenote" ] [ text "A security company with renowned reputation." ]
|
||||||
|
, text ", before that, I was working under"
|
||||||
, text ", before that, I was working under", text " "
|
, text " "
|
||||||
, quicklinks "bshield" "BShield"
|
, quicklinks "bshield" "BShield"
|
||||||
, label [ class "sidenote-number" ] []
|
, label [ class "sidenote-number" ] []
|
||||||
, span [ class "sidenote" ] [ text "A mobile protection platform." ]
|
, span [ class "sidenote" ] [ text "A mobile protection platform." ]
|
||||||
|
, text "."
|
||||||
, text ".", text " "
|
, text " "
|
||||||
|
|
||||||
, text "BShield is now under Verichains, serving as the product of Verichains. My work including research for both Verichains and BShield, blockchain and mobile security."
|
, text "BShield is now under Verichains, serving as the product of Verichains. My work including research for both Verichains and BShield, blockchain and mobile security."
|
||||||
]
|
]
|
||||||
, p []
|
, p []
|
||||||
[ text "I was an active member of", text " "
|
[ text "I was an active member of"
|
||||||
|
, text " "
|
||||||
, quicklinks "efiens" "Efiens"
|
, quicklinks "efiens" "Efiens"
|
||||||
, label [ class "sidenote-number" ] []
|
, label [ class "sidenote-number" ] []
|
||||||
, span [ class "sidenote" ] [ text "CTF team of Ho Chi Minh University of Technology, Vietnam. Our team has won prizes in national and international competitions. Founded 2016, inactive since 2021, superceeded by", text " ", quicklinks "bkisc" "BKISC", text "." ]
|
, span [ class "sidenote" ] [ text "CTF team of Ho Chi Minh University of Technology, Vietnam. Our team has won prizes in national and international competitions. Founded 2016, inactive since 2021, superceeded by", text " ", quicklinks "bkisc" "BKISC", text "." ]
|
||||||
, text ".", text " "
|
, text "."
|
||||||
|
, text " "
|
||||||
, text "While a member, I actively play CTF under the category Reverse Engineering. I became a leader in the later days of the team, guiding young members into CTF and Computer Security."
|
, text "While a member, I actively play CTF under the category Reverse Engineering. I became a leader in the later days of the team, guiding young members into CTF and Computer Security."
|
||||||
]
|
]
|
||||||
, p []
|
, p []
|
||||||
@ -137,23 +140,29 @@ view app shared =
|
|||||||
, publications
|
, publications
|
||||||
, blabla
|
, blabla
|
||||||
]
|
]
|
||||||
]]
|
]
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
projects : Html msg
|
projects : Html msg
|
||||||
projects =
|
projects =
|
||||||
div []
|
div []
|
||||||
[ section []
|
[ section []
|
||||||
[ h2 [] [text "TSSHOCK"]
|
[ h2 [] [ text "TSSHOCK" ]
|
||||||
, p []
|
, p []
|
||||||
[ text "I was a part of the team that helped unveiling the vulnerabilities in many implementations of ECDSA Threshold Signature Scheme protocol by Gennaro and Goldfeder"
|
[ text "I was a part of the team that helped unveiling the vulnerabilities in many implementations of ECDSA Threshold Signature Scheme protocol by Gennaro and Goldfeder"
|
||||||
, label [ class "sidenote-number" ] []
|
, label [ class "sidenote-number" ] []
|
||||||
, span [ class "sidenote" ] [ text "In public key cryptosystem, signing messages usually involves one party with one private key. Threshold Signature Scheme allows more than one party to participate to the signing process while keeping only one private key used. Missing a signing party would be impossible to sign messages. Across the whole process, the private key is kept unknown to all parties. Gennaro and Goldfeder (GG18/GG20) proposed a protocol, which is now superceeded by MPC-CMP." ]
|
, span [ class "sidenote" ] [ text "In public key cryptosystem, signing messages usually involves one party with one private key. Threshold Signature Scheme allows more than one party to participate to the signing process while keeping only one private key used. Missing a signing party would be impossible to sign messages. Across the whole process, the private key is kept unknown to all parties. Gennaro and Goldfeder (GG18/GG20) proposed a protocol, which is now superceeded by MPC-CMP." ]
|
||||||
, text ".", text " "
|
, text "."
|
||||||
|
, text " "
|
||||||
, text "Our findings was publicly announced and published at two major security conventions,"
|
, text "Our findings was publicly announced and published at two major security conventions,"
|
||||||
, text " ", quicklinks "tsshockblackhat" "Black Hat USA 2023"
|
, text " "
|
||||||
, text " ", text "and"
|
, quicklinks "tsshockblackhat" "Black Hat USA 2023"
|
||||||
, text " ", quicklinks "tsshockhitb" "Hack In The Box Phuket 2023"
|
, text " "
|
||||||
|
, text "and"
|
||||||
|
, text " "
|
||||||
|
, quicklinks "tsshockhitb" "Hack In The Box Phuket 2023"
|
||||||
, label [ class "sidenote-number" ] []
|
, label [ class "sidenote-number" ] []
|
||||||
, span [ class "sidenote" ]
|
, span [ class "sidenote" ]
|
||||||
[ text "Duy Hieu Nguyen, Anh Khoa Nguyen, Huu Giap Nguyen, Thanh Nguyen and Anh Quynh Nguyen. TSSHOCK: Breaking MPC Wallets and Digital Custodians for $BILLION$ Profit. 2023"
|
[ text "Duy Hieu Nguyen, Anh Khoa Nguyen, Huu Giap Nguyen, Thanh Nguyen and Anh Quynh Nguyen. TSSHOCK: Breaking MPC Wallets and Digital Custodians for $BILLION$ Profit. 2023"
|
||||||
@ -162,7 +171,7 @@ projects =
|
|||||||
]
|
]
|
||||||
]
|
]
|
||||||
, section []
|
, section []
|
||||||
[ h2 [] [text "Vietnam Citizen Card Audits"]
|
[ h2 [] [ text "Vietnam Citizen Card Audits" ]
|
||||||
, p []
|
, p []
|
||||||
[ text "I was working on an application using our country citizen card when I realized that many (in production) NFC eKYC applications might not working properly because they lack the understanding of cryptographic protocols required for securely communication with the NFC card. My team and I built a simulation device for the ICAO 9303"
|
[ text "I was working on an application using our country citizen card when I realized that many (in production) NFC eKYC applications might not working properly because they lack the understanding of cryptographic protocols required for securely communication with the NFC card. My team and I built a simulation device for the ICAO 9303"
|
||||||
, label [ class "sidenote-number" ] []
|
, label [ class "sidenote-number" ] []
|
||||||
@ -176,20 +185,21 @@ projects =
|
|||||||
]
|
]
|
||||||
]
|
]
|
||||||
, section []
|
, section []
|
||||||
[ h2 [] [text "Research Mach-O binary format"]
|
[ h2 [] [ text "Research Mach-O binary format" ]
|
||||||
, p []
|
, p []
|
||||||
[ text "Mach-O is the binary format used exclusively in Apple devices. I started researching about this format when I first joined BShield. I had an idea back then about how we can simulate the loader to control imports. Years later, I build a Proof of Concept around the idea. Using loader simulation, we can build an obfuscator or a hooking tool. Details are disclosed in the paper."
|
[ text "Mach-O is the binary format used exclusively in Apple devices. I started researching about this format when I first joined BShield. I had an idea back then about how we can simulate the loader to control imports. Years later, I build a Proof of Concept around the idea. Using loader simulation, we can build an obfuscator or a hooking tool. Details are disclosed in the paper."
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
, section []
|
, section []
|
||||||
[ h2 [] [text "LLVM based Obfuscation"]
|
[ h2 [] [ text "LLVM based Obfuscation" ]
|
||||||
, p []
|
, p []
|
||||||
[ text "I fork and built an obfuscator based on LLVM, first mentioned in Obfuscator-LLVM"
|
[ text "I fork and built an obfuscator based on LLVM, first mentioned in Obfuscator-LLVM"
|
||||||
, label [ class "sidenote-number" ] []
|
, label [ class "sidenote-number" ] []
|
||||||
, span [ class "sidenote" ]
|
, span [ class "sidenote" ]
|
||||||
[ text "Pascal Junod and Julien Rinaldini and Johan Wehrli and Julie Michielin. Obfuscator-LLVM -- Software Protection for the Masses. 2015."
|
[ text "Pascal Junod and Julien Rinaldini and Johan Wehrli and Julie Michielin. Obfuscator-LLVM -- Software Protection for the Masses. 2015."
|
||||||
]
|
]
|
||||||
, text ".", text " "
|
, text "."
|
||||||
|
, text " "
|
||||||
, text "With my team, we ported Mixed Boolean-Arithmetic"
|
, text "With my team, we ported Mixed Boolean-Arithmetic"
|
||||||
, label [ class "sidenote-number" ] []
|
, label [ class "sidenote-number" ] []
|
||||||
, span [ class "sidenote" ]
|
, span [ class "sidenote" ]
|
||||||
@ -203,25 +213,27 @@ projects =
|
|||||||
]
|
]
|
||||||
]
|
]
|
||||||
, section []
|
, section []
|
||||||
[ h2 [] [text "Windows Live Memory Forensics"]
|
[ h2 [] [ text "Windows Live Memory Forensics" ]
|
||||||
, p []
|
, p []
|
||||||
[ text "My first research project started as a bachelor thesis. I built a memory forensics tool working on virtual memory. For the success of this project, I have learned Windows kernel driver, memory forensics techniques, and studied the Volatility source code. The prototype was capable of inspecting the kernel memory, viewing kernel global variables, and perform Pool Tag Quick Scanning"
|
[ text "My first research project started as a bachelor thesis. I built a memory forensics tool working on virtual memory. For the success of this project, I have learned Windows kernel driver, memory forensics techniques, and studied the Volatility source code. The prototype was capable of inspecting the kernel memory, viewing kernel global variables, and perform Pool Tag Quick Scanning"
|
||||||
, label [ class "sidenote-number" ] []
|
, label [ class "sidenote-number" ] []
|
||||||
, span [ class "sidenote" ]
|
, span [ class "sidenote" ]
|
||||||
[ text "Joe T. Sylve, Vico Marziale, Golden G. Richard. Pool tag quick scanning for windows memory analysis. 2016."
|
[ text "Joe T. Sylve, Vico Marziale, Golden G. Richard. Pool tag quick scanning for windows memory analysis. 2016."
|
||||||
]
|
]
|
||||||
, text ".", text " "
|
, text "."
|
||||||
|
, text " "
|
||||||
, text "The work is later improved to search for code injection by my junior in Efiens."
|
, text "The work is later improved to search for code injection by my junior in Efiens."
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
publications : Html msg
|
publications : Html msg
|
||||||
publications =
|
publications =
|
||||||
section []
|
section []
|
||||||
[ h1 [] [text "Publications"]
|
[ h1 [] [ text "Publications" ]
|
||||||
, p [] [
|
, p []
|
||||||
text "Most of my publications are drafts and not reviewed paper. Because I am not in an academic environment so I do not know how to publish."
|
[ text "Most of my publications are drafts and not reviewed paper. Because I am not in an academic environment so I do not know how to publish."
|
||||||
]
|
]
|
||||||
, withSpacing (p [])
|
, withSpacing (p [])
|
||||||
[ text "Simulating Loader for Mach-O Binary Obfuscation and Hooking."
|
[ text "Simulating Loader for Mach-O Binary Obfuscation and Hooking."
|
||||||
@ -250,7 +262,7 @@ publications =
|
|||||||
, quicklinks "tsshockvideohitb" "[HITB Recordings]"
|
, quicklinks "tsshockvideohitb" "[HITB Recordings]"
|
||||||
]
|
]
|
||||||
, br [] []
|
, br [] []
|
||||||
, h2 [] [text "Dissertations"]
|
, h2 [] [ text "Dissertations" ]
|
||||||
, withSpacing (p [])
|
, withSpacing (p [])
|
||||||
[ text "After I graduated, I often advise undergraduate students on their dissertations."
|
[ text "After I graduated, I often advise undergraduate students on their dissertations."
|
||||||
, text "The list below contains my dissertation and dissertations I advised."
|
, text "The list below contains my dissertation and dissertations I advised."
|
||||||
@ -297,6 +309,7 @@ publications =
|
|||||||
, text "Advisors: An Khuong Nguyen, Anh Khoa Nguyen."
|
, text "Advisors: An Khuong Nguyen, Anh Khoa Nguyen."
|
||||||
, br [] []
|
, br [] []
|
||||||
, text "Year: Expecting 2025"
|
, text "Year: Expecting 2025"
|
||||||
|
|
||||||
-- , br [] []
|
-- , br [] []
|
||||||
-- , quicklinks "powershellsandbox" "[pdf]"
|
-- , quicklinks "powershellsandbox" "[pdf]"
|
||||||
]
|
]
|
||||||
@ -308,11 +321,13 @@ publications =
|
|||||||
, text "Advisors: An Khuong Nguyen, Anh Khoa Nguyen."
|
, text "Advisors: An Khuong Nguyen, Anh Khoa Nguyen."
|
||||||
, br [] []
|
, br [] []
|
||||||
, text "Year: Expecting 2025"
|
, text "Year: Expecting 2025"
|
||||||
|
|
||||||
-- , br [] []
|
-- , br [] []
|
||||||
-- , quicklinks "powershellsandbox" "[pdf]"
|
-- , quicklinks "powershellsandbox" "[pdf]"
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
blabla : Html msg
|
blabla : Html msg
|
||||||
blabla =
|
blabla =
|
||||||
section []
|
section []
|
||||||
@ -323,69 +338,140 @@ blabla =
|
|||||||
, quicklinks "https://research.ralfj.de/thesis.html" "thesis"
|
, quicklinks "https://research.ralfj.de/thesis.html" "thesis"
|
||||||
, label [ class "sidenote-number" ] []
|
, label [ class "sidenote-number" ] []
|
||||||
, span [ class "sidenote" ] [ text "Jung, Ralf. Understanding and evolving the Rust programming language. 2020." ]
|
, span [ class "sidenote" ] [ text "Jung, Ralf. Understanding and evolving the Rust programming language. 2020." ]
|
||||||
, text ",", text " "
|
, text ","
|
||||||
|
, text " "
|
||||||
, text "I amazed how clean the text was due to all the references are introduced at the right side. Later that I found out the format was based on Tufte design and began using it for this website."
|
, text "I amazed how clean the text was due to all the references are introduced at the right side. Later that I found out the format was based on Tufte design and began using it for this website."
|
||||||
]
|
]
|
||||||
, p []
|
, p []
|
||||||
[ text "I use Neovim, can't live without those Vim motions. Neovim GUI that I use is"
|
[ text "I use Neovim, can't live without those Vim motions. Neovim GUI that I use is"
|
||||||
, text " "
|
, text " "
|
||||||
, quicklinks "https://neovide.dev/" "Neovide"
|
, quicklinks "https://neovide.dev/" "Neovide"
|
||||||
, text ",", text " "
|
, text ","
|
||||||
|
, text " "
|
||||||
, text "which I also contributed to add the prompts on Windows right-click menu and copy pasting while on remote connection."
|
, text "which I also contributed to add the prompts on Windows right-click menu and copy pasting while on remote connection."
|
||||||
]
|
]
|
||||||
, p []
|
, p []
|
||||||
[ text "Linux distribution that I prefer is"
|
[ text "Linux distribution that I prefer is"
|
||||||
, text " "
|
, text " "
|
||||||
, quicklinks "https://artixlinux.org/" "Artix Linux"
|
, quicklinks "https://artixlinux.org/" "Artix Linux"
|
||||||
, text ".", text " "
|
, text "."
|
||||||
, text "I enjoy when everything is barebone and at the edge, most setup are mine and I can figure out things faster when I am the one doing the setup. I choose Artix over the vanila Arch Linux because does there is no systemd." ]
|
, text " "
|
||||||
|
, text "I enjoy when everything is barebone and at the edge, most setup are mine and I can figure out things faster when I am the one doing the setup. I choose Artix over the vanila Arch Linux because does there is no systemd."
|
||||||
|
]
|
||||||
, p []
|
, p []
|
||||||
[ text "You might not see me active on Github, because I have my own Git server storing my projects (personal and job). I also run my own VPN server through Wireguard. I just like doing many things by myself."
|
[ text "You might not see me active on Github, because I have my own Git server storing my projects (personal and job). I also run my own VPN server through Wireguard. I just like doing many things by myself."
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
quicklinks link title =
|
quicklinks link title =
|
||||||
let
|
let
|
||||||
linkexternal src = Link.link (Link.external src) [target "_blank"] [text title]
|
linkexternal src =
|
||||||
linkinternal src = case src of
|
Link.link (Link.external src) [ target "_blank" ] [ text title ]
|
||||||
"blog" -> Link.link (Link.internal (Route.Blog__Slug_ { slug = "" })) [] [ text title ]
|
|
||||||
"osx" -> Link.link (Link.internal (Route.Osx__Slug_ { slug = "" })) [] [ text title ]
|
linkinternal src =
|
||||||
"book" -> Link.link (Link.internal Route.Book) [] [ text title ]
|
case src of
|
||||||
_ -> Link.link (Link.external "") [] [text title]
|
"blog" ->
|
||||||
|
Link.link (Link.internal (Route.Blog__Slug_ { slug = "" })) [] [ text title ]
|
||||||
|
|
||||||
|
"osx" ->
|
||||||
|
Link.link (Link.internal (Route.Osx__Slug_ { slug = "" })) [] [ text title ]
|
||||||
|
|
||||||
|
"book" ->
|
||||||
|
Link.link (Link.internal Route.Book) [] [ text title ]
|
||||||
|
|
||||||
|
_ ->
|
||||||
|
Link.link (Link.external "") [] [ text title ]
|
||||||
in
|
in
|
||||||
case link of
|
case link of
|
||||||
"github" -> linkexternal "https://github.com/nganhkhoa"
|
"github" ->
|
||||||
"git" -> linkexternal "https://git.nganhkhoa.com"
|
linkexternal "https://github.com/nganhkhoa"
|
||||||
"efiens" -> linkexternal "https://blog.efiens.com/author/luibo"
|
|
||||||
"bshield" -> linkexternal "https://bshield.io"
|
|
||||||
"verichains" -> linkexternal "https://verichains.io"
|
|
||||||
"bkisc" -> linkexternal "https://bkisc.com/"
|
|
||||||
"elm" -> linkexternal "https://elm-pages.com"
|
|
||||||
-- tsshock
|
|
||||||
"gg" -> linkexternal "https://eprint.iacr.org/2019/114"
|
|
||||||
"tsshockblackhat" -> linkexternal "https://www.blackhat.com/us-23/briefings/schedule/#tsshock-breaking-mpc-wallets-and-digital-custodians-for-billion-profit-33343"
|
|
||||||
"tsshockhitb" -> linkexternal "https://conference.hitb.org/hitbsecconf2023hkt/session/tsshock-breaking-mpc-wallets-and-digital-custodians/"
|
|
||||||
"tsshockwebsite" -> linkexternal "https://verichains.io/tsshock"
|
|
||||||
"tsshockwhitepaper" -> linkexternal "https://www.verichains.io/tsshock/verichains-tsshock-wp-v1.0.pdf"
|
|
||||||
"tsshockvideohitb" -> linkexternal "https://youtu.be/1ks2jcS7UE4"
|
|
||||||
"tsshockvideoblackhat" -> linkexternal "https://youtu.be/5mlQb8PEF3A"
|
|
||||||
-- ollvm
|
|
||||||
"ollvm" -> linkexternal "https://doi.org/10.1109/SPRO.2015.10"
|
|
||||||
"mba" -> linkexternal "https://doi.org/10.1007/978-3-540-77535-5_5"
|
|
||||||
"tetctf2022" -> linkexternal "https://twitter.com/hgarrereyn/status/1477919411977830402"
|
|
||||||
-- memory forensics
|
|
||||||
"poolscan" -> linkexternal "https://doi.org/10.1016/j.diin.2016.01.005"
|
|
||||||
-- site resources
|
|
||||||
"cv" -> linkexternal "/cv.pdf"
|
|
||||||
"blog" -> linkinternal "blog"
|
|
||||||
"osx" -> linkinternal "osx"
|
|
||||||
"book" -> linkinternal "book"
|
|
||||||
-- pdfs
|
|
||||||
"memorypoolscan" -> linkexternal "https://drive.google.com/file/d/1Z_cKtBsi_gm8ugsrnAEPo-Wmx9GAuaSK/view?usp=sharing"
|
|
||||||
"memoryinjection" -> linkexternal "https://drive.google.com/file/d/1X18tr4OvcNYRoyxzTcsxM_MgjcqVW1sk/view?usp=sharing"
|
|
||||||
"powershellsandbox" -> linkexternal "https://drive.google.com/file/d/1Fm1YVAxD-A-zjVvRwBPa-IhZ1Y8ImEyv/view?usp=sharing"
|
|
||||||
"macho" -> linkexternal "/papers/macho-obfuscation.pdf"
|
|
||||||
"macho-git" -> linkexternal "https://git.nganhkhoa.com/dot/macho"
|
|
||||||
"live-memory-forensics" -> linkexternal "/papers/live-memory-forensics.pdf"
|
|
||||||
_ -> linkexternal link
|
|
||||||
|
|
||||||
|
"git" ->
|
||||||
|
linkexternal "https://git.nganhkhoa.com"
|
||||||
|
|
||||||
|
"efiens" ->
|
||||||
|
linkexternal "https://blog.efiens.com/author/luibo"
|
||||||
|
|
||||||
|
"bshield" ->
|
||||||
|
linkexternal "https://bshield.io"
|
||||||
|
|
||||||
|
"verichains" ->
|
||||||
|
linkexternal "https://verichains.io"
|
||||||
|
|
||||||
|
"bkisc" ->
|
||||||
|
linkexternal "https://bkisc.com/"
|
||||||
|
|
||||||
|
"elm" ->
|
||||||
|
linkexternal "https://elm-pages.com"
|
||||||
|
|
||||||
|
-- tsshock
|
||||||
|
"gg" ->
|
||||||
|
linkexternal "https://eprint.iacr.org/2019/114"
|
||||||
|
|
||||||
|
"tsshockblackhat" ->
|
||||||
|
linkexternal "https://www.blackhat.com/us-23/briefings/schedule/#tsshock-breaking-mpc-wallets-and-digital-custodians-for-billion-profit-33343"
|
||||||
|
|
||||||
|
"tsshockhitb" ->
|
||||||
|
linkexternal "https://conference.hitb.org/hitbsecconf2023hkt/session/tsshock-breaking-mpc-wallets-and-digital-custodians/"
|
||||||
|
|
||||||
|
"tsshockwebsite" ->
|
||||||
|
linkexternal "https://verichains.io/tsshock"
|
||||||
|
|
||||||
|
"tsshockwhitepaper" ->
|
||||||
|
linkexternal "https://www.verichains.io/tsshock/verichains-tsshock-wp-v1.0.pdf"
|
||||||
|
|
||||||
|
"tsshockvideohitb" ->
|
||||||
|
linkexternal "https://youtu.be/1ks2jcS7UE4"
|
||||||
|
|
||||||
|
"tsshockvideoblackhat" ->
|
||||||
|
linkexternal "https://youtu.be/5mlQb8PEF3A"
|
||||||
|
|
||||||
|
-- ollvm
|
||||||
|
"ollvm" ->
|
||||||
|
linkexternal "https://doi.org/10.1109/SPRO.2015.10"
|
||||||
|
|
||||||
|
"mba" ->
|
||||||
|
linkexternal "https://doi.org/10.1007/978-3-540-77535-5_5"
|
||||||
|
|
||||||
|
"tetctf2022" ->
|
||||||
|
linkexternal "https://twitter.com/hgarrereyn/status/1477919411977830402"
|
||||||
|
|
||||||
|
-- memory forensics
|
||||||
|
"poolscan" ->
|
||||||
|
linkexternal "https://doi.org/10.1016/j.diin.2016.01.005"
|
||||||
|
|
||||||
|
-- site resources
|
||||||
|
"cv" ->
|
||||||
|
linkexternal "/cv.pdf"
|
||||||
|
|
||||||
|
"blog" ->
|
||||||
|
linkinternal "blog"
|
||||||
|
|
||||||
|
"osx" ->
|
||||||
|
linkinternal "osx"
|
||||||
|
|
||||||
|
"book" ->
|
||||||
|
linkinternal "book"
|
||||||
|
|
||||||
|
-- pdfs
|
||||||
|
"memorypoolscan" ->
|
||||||
|
linkexternal "https://drive.google.com/file/d/1Z_cKtBsi_gm8ugsrnAEPo-Wmx9GAuaSK/view?usp=sharing"
|
||||||
|
|
||||||
|
"memoryinjection" ->
|
||||||
|
linkexternal "https://drive.google.com/file/d/1X18tr4OvcNYRoyxzTcsxM_MgjcqVW1sk/view?usp=sharing"
|
||||||
|
|
||||||
|
"powershellsandbox" ->
|
||||||
|
linkexternal "https://drive.google.com/file/d/1Fm1YVAxD-A-zjVvRwBPa-IhZ1Y8ImEyv/view?usp=sharing"
|
||||||
|
|
||||||
|
"macho" ->
|
||||||
|
linkexternal "/papers/macho-obfuscation.pdf"
|
||||||
|
|
||||||
|
"macho-git" ->
|
||||||
|
linkexternal "https://git.nganhkhoa.com/dot/macho"
|
||||||
|
|
||||||
|
"live-memory-forensics" ->
|
||||||
|
linkexternal "/papers/live-memory-forensics.pdf"
|
||||||
|
|
||||||
|
_ ->
|
||||||
|
linkexternal link
|
||||||
|
@ -10,20 +10,18 @@ import Html.Styled exposing (..)
|
|||||||
import Html.Styled.Attributes as Attributes
|
import Html.Styled.Attributes as Attributes
|
||||||
import Json.Decode as Decode exposing (Decoder)
|
import Json.Decode as Decode exposing (Decoder)
|
||||||
import Json.Decode.Extra
|
import Json.Decode.Extra
|
||||||
|
import Link
|
||||||
|
import Markdown.Block
|
||||||
|
import Markdown.Renderer
|
||||||
|
import MarkdownCodec
|
||||||
import Pages.Url
|
import Pages.Url
|
||||||
import PagesMsg exposing (PagesMsg)
|
import PagesMsg exposing (PagesMsg)
|
||||||
import Route exposing (Route)
|
import Route exposing (Route)
|
||||||
import RouteBuilder exposing (App, StatelessRoute)
|
import RouteBuilder exposing (App, StatelessRoute)
|
||||||
import Shared
|
import Shared
|
||||||
import View exposing (View)
|
|
||||||
import Link
|
|
||||||
|
|
||||||
|
|
||||||
import Markdown.Block
|
|
||||||
import Markdown.Renderer
|
|
||||||
import MarkdownCodec
|
|
||||||
import TailwindMarkdownRenderer
|
|
||||||
import Tailwind.Utilities as Tw
|
import Tailwind.Utilities as Tw
|
||||||
|
import TailwindMarkdownRenderer
|
||||||
|
import View exposing (View)
|
||||||
|
|
||||||
|
|
||||||
type alias Model =
|
type alias Model =
|
||||||
@ -33,9 +31,11 @@ type alias Model =
|
|||||||
type alias Msg =
|
type alias Msg =
|
||||||
()
|
()
|
||||||
|
|
||||||
|
|
||||||
type alias RouteParams =
|
type alias RouteParams =
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
route : StatelessRoute RouteParams Data ActionData
|
route : StatelessRoute RouteParams Data ActionData
|
||||||
route =
|
route =
|
||||||
RouteBuilder.single
|
RouteBuilder.single
|
||||||
@ -46,7 +46,8 @@ route =
|
|||||||
|
|
||||||
|
|
||||||
type alias Data =
|
type alias Data =
|
||||||
List (Route, Article.ArticleMetadata)
|
List ( Route, Article.ArticleMetadata )
|
||||||
|
|
||||||
|
|
||||||
type alias ActionData =
|
type alias ActionData =
|
||||||
{}
|
{}
|
||||||
@ -57,6 +58,7 @@ data =
|
|||||||
Article.osxAllMetadata
|
Article.osxAllMetadata
|
||||||
|> BackendTask.allowFatal
|
|> BackendTask.allowFatal
|
||||||
|
|
||||||
|
|
||||||
head :
|
head :
|
||||||
App Data ActionData RouteParams
|
App Data ActionData RouteParams
|
||||||
-> List Head.Tag
|
-> List Head.Tag
|
||||||
@ -88,26 +90,28 @@ view app shared =
|
|||||||
[ p []
|
[ p []
|
||||||
[ text "For years, I learned how the Apple binary format works. There are blog posts that I wrote when I first started learning about them. If you want to read them, here they are below, ported from the efiens blog."
|
[ text "For years, I learned how the Apple binary format works. There are blog posts that I wrote when I first started learning about them. If you want to read them, here they are below, ported from the efiens blog."
|
||||||
, ul []
|
, ul []
|
||||||
(List.map (\item -> li [] [item]) oldBlogs)
|
(List.map (\item -> li [] [ item ]) oldBlogs)
|
||||||
, br [] []
|
, br [] []
|
||||||
, text "Through understanding the loading process of Mach-O, I devised a technique for obfuscation and hooking. In the following whitepaper, I writeup all steps in this obfuscation scheme."
|
, text "Through understanding the loading process of Mach-O, I devised a technique for obfuscation and hooking. In the following whitepaper, I writeup all steps in this obfuscation scheme."
|
||||||
, br [] []
|
, br [] []
|
||||||
, Link.link (Link.external whitepaper)
|
, Link.link (Link.external whitepaper)
|
||||||
[Attributes.target "_blank"]
|
[ Attributes.target "_blank" ]
|
||||||
[text "whitepaper"]
|
[ text "whitepaper" ]
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
oldBlogs : List (Html msg)
|
oldBlogs : List (Html msg)
|
||||||
oldBlogs =
|
oldBlogs =
|
||||||
[ (Link.link (Link.internal (Route.Osx__Slug_ { slug = "macho" })) [] [text "Macho"] )
|
[ Link.link (Link.internal (Route.Osx__Slug_ { slug = "macho" })) [] [ text "Macho" ]
|
||||||
, (Link.link (Link.internal (Route.Osx__Slug_ { slug = "linker" })) [] [text "Linker"] )
|
, Link.link (Link.internal (Route.Osx__Slug_ { slug = "linker" })) [] [ text "Linker" ]
|
||||||
, (Link.link (Link.internal (Route.Osx__Slug_ { slug = "fairplay" })) [] [text "Fairplay"] )
|
, Link.link (Link.internal (Route.Osx__Slug_ { slug = "fairplay" })) [] [ text "Fairplay" ]
|
||||||
, (Link.link (Link.internal (Route.Osx__Slug_ { slug = "injection" })) [] [text "Injection"] )
|
, Link.link (Link.internal (Route.Osx__Slug_ { slug = "injection" })) [] [ text "Injection" ]
|
||||||
]
|
]
|
||||||
|
|
||||||
whitepaper : String
|
|
||||||
whitepaper = "/papers/macho-obfuscation.pdf"
|
|
||||||
|
|
||||||
|
whitepaper : String
|
||||||
|
whitepaper =
|
||||||
|
"/papers/macho-obfuscation.pdf"
|
||||||
|
@ -7,23 +7,21 @@ import FatalError exposing (FatalError)
|
|||||||
import Head
|
import Head
|
||||||
import Head.Seo as Seo
|
import Head.Seo as Seo
|
||||||
import Html.Styled exposing (..)
|
import Html.Styled exposing (..)
|
||||||
import Html.Styled.Attributes exposing (style, class)
|
import Html.Styled.Attributes exposing (class, style)
|
||||||
import Link exposing (Link)
|
|
||||||
import Json.Decode as Decode exposing (Decoder)
|
import Json.Decode as Decode exposing (Decoder)
|
||||||
import Json.Decode.Extra
|
import Json.Decode.Extra
|
||||||
import Pages.Url
|
import Link exposing (Link)
|
||||||
import PagesMsg exposing (PagesMsg)
|
|
||||||
import RouteBuilder exposing (App, StatelessRoute)
|
|
||||||
import Route
|
|
||||||
import Shared
|
|
||||||
import View exposing (View)
|
|
||||||
|
|
||||||
|
|
||||||
import Markdown.Block
|
import Markdown.Block
|
||||||
import Markdown.Renderer
|
import Markdown.Renderer
|
||||||
import MarkdownCodec
|
import MarkdownCodec
|
||||||
import TailwindMarkdownRenderer
|
import Pages.Url
|
||||||
|
import PagesMsg exposing (PagesMsg)
|
||||||
|
import Route
|
||||||
|
import RouteBuilder exposing (App, StatelessRoute)
|
||||||
|
import Shared
|
||||||
import Tailwind.Utilities as Tw
|
import Tailwind.Utilities as Tw
|
||||||
|
import TailwindMarkdownRenderer
|
||||||
|
import View exposing (View)
|
||||||
|
|
||||||
|
|
||||||
type alias Model =
|
type alias Model =
|
||||||
@ -64,6 +62,7 @@ type alias Data =
|
|||||||
, body : List Markdown.Block.Block
|
, body : List Markdown.Block.Block
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
type alias ActionData =
|
type alias ActionData =
|
||||||
{}
|
{}
|
||||||
|
|
||||||
@ -81,6 +80,7 @@ type alias ArticleMetadata =
|
|||||||
, subtitle : String
|
, subtitle : String
|
||||||
, description : String
|
, description : String
|
||||||
, published : Date
|
, published : Date
|
||||||
|
|
||||||
-- , image : Pages.Url.Url
|
-- , image : Pages.Url.Url
|
||||||
, draft : Bool
|
, draft : Bool
|
||||||
}
|
}
|
||||||
@ -111,6 +111,7 @@ frontmatterDecoder =
|
|||||||
|> Decode.map (Maybe.withDefault False)
|
|> Decode.map (Maybe.withDefault False)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
head :
|
head :
|
||||||
App Data ActionData RouteParams
|
App Data ActionData RouteParams
|
||||||
-> List Head.Tag
|
-> List Head.Tag
|
||||||
@ -136,7 +137,9 @@ view :
|
|||||||
-> Shared.Model
|
-> Shared.Model
|
||||||
-> View (PagesMsg Msg)
|
-> View (PagesMsg Msg)
|
||||||
view app shared =
|
view app shared =
|
||||||
let rendered = (app.data.body |> Markdown.Renderer.render TailwindMarkdownRenderer.renderer) |> Result.withDefault []
|
let
|
||||||
|
rendered =
|
||||||
|
(app.data.body |> Markdown.Renderer.render TailwindMarkdownRenderer.renderer) |> Result.withDefault []
|
||||||
in
|
in
|
||||||
{ title = app.data.metadata.title
|
{ title = app.data.metadata.title
|
||||||
, body =
|
, body =
|
||||||
|
@ -3,18 +3,18 @@ module Shared exposing (Data, Model, Msg(..), SharedMsg(..), template)
|
|||||||
import BackendTask exposing (BackendTask)
|
import BackendTask exposing (BackendTask)
|
||||||
import Effect exposing (Effect)
|
import Effect exposing (Effect)
|
||||||
import FatalError exposing (FatalError)
|
import FatalError exposing (FatalError)
|
||||||
|
import Header exposing (header)
|
||||||
import Html exposing (Html)
|
import Html exposing (Html)
|
||||||
import Html.Styled
|
import Html.Styled
|
||||||
import Html.Styled.Events
|
import Html.Styled.Events
|
||||||
|
import Link exposing (Link)
|
||||||
import Pages.Flags
|
import Pages.Flags
|
||||||
import Pages.PageUrl exposing (PageUrl)
|
import Pages.PageUrl exposing (PageUrl)
|
||||||
import UrlPath exposing (UrlPath)
|
|
||||||
import Route exposing (Route)
|
import Route exposing (Route)
|
||||||
import SharedTemplate exposing (SharedTemplate)
|
import SharedTemplate exposing (SharedTemplate)
|
||||||
|
import UrlPath exposing (UrlPath)
|
||||||
import View exposing (View)
|
import View exposing (View)
|
||||||
|
|
||||||
import Header exposing (header)
|
|
||||||
import Link exposing (Link)
|
|
||||||
|
|
||||||
template : SharedTemplate Msg Model Data msg
|
template : SharedTemplate Msg Model Data msg
|
||||||
template =
|
template =
|
||||||
@ -96,9 +96,9 @@ view :
|
|||||||
-> { body : List (Html msg), title : String }
|
-> { body : List (Html msg), title : String }
|
||||||
view tableOfContents page model toMsg pageView =
|
view tableOfContents page model toMsg pageView =
|
||||||
{ body =
|
{ body =
|
||||||
[
|
[ header
|
||||||
header
|
|
||||||
|> Html.Styled.toUnstyled
|
|> Html.Styled.toUnstyled
|
||||||
|
|
||||||
-- ((View.Header.view ToggleMobileMenu 123 page.path
|
-- ((View.Header.view ToggleMobileMenu 123 page.path
|
||||||
-- |> Html.Styled.map toMsg
|
-- |> Html.Styled.map toMsg
|
||||||
-- )
|
-- )
|
||||||
@ -110,6 +110,9 @@ view tableOfContents page model toMsg pageView =
|
|||||||
]
|
]
|
||||||
, title = pageView.title
|
, title = pageView.title
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-- view sharedData page model toMsg pageView =
|
-- view sharedData page model toMsg pageView =
|
||||||
-- { body =
|
-- { body =
|
||||||
-- [ Html.Styled.nav []
|
-- [ Html.Styled.nav []
|
||||||
@ -118,7 +121,6 @@ view tableOfContents page model toMsg pageView =
|
|||||||
-- [ Html.Styled.text
|
-- [ Html.Styled.text
|
||||||
-- (if model.showMenu then
|
-- (if model.showMenu then
|
||||||
-- "Close Menu"
|
-- "Close Menu"
|
||||||
|
|
||||||
-- else
|
-- else
|
||||||
-- "Open Menu"
|
-- "Open Menu"
|
||||||
-- )
|
-- )
|
||||||
@ -128,7 +130,6 @@ view tableOfContents page model toMsg pageView =
|
|||||||
-- [ Html.Styled.li [] [ Html.Styled.text "Menu item 1" ]
|
-- [ Html.Styled.li [] [ Html.Styled.text "Menu item 1" ]
|
||||||
-- , Html.Styled.li [] [ Html.Styled.text "Menu item 2" ]
|
-- , Html.Styled.li [] [ Html.Styled.text "Menu item 2" ]
|
||||||
-- ]
|
-- ]
|
||||||
|
|
||||||
-- else
|
-- else
|
||||||
-- Html.Styled.text ""
|
-- Html.Styled.text ""
|
||||||
-- ]
|
-- ]
|
||||||
|
@ -16,6 +16,7 @@ config =
|
|||||||
head : BackendTask FatalError (List Head.Tag)
|
head : BackendTask FatalError (List Head.Tag)
|
||||||
head =
|
head =
|
||||||
[ Head.metaName "viewport" (Head.raw "width=device-width,initial-scale=1")
|
[ Head.metaName "viewport" (Head.raw "width=device-width,initial-scale=1")
|
||||||
|
|
||||||
-- , Head.nonLoadingNode "link"
|
-- , Head.nonLoadingNode "link"
|
||||||
-- [ ( "rel", Head.raw "stylesheet" )
|
-- [ ( "rel", Head.raw "stylesheet" )
|
||||||
-- , ( "crossorigin", Head.raw "anonymous" )
|
-- , ( "crossorigin", Head.raw "anonymous" )
|
||||||
|
@ -1,14 +1,18 @@
|
|||||||
module Article exposing (..)
|
module Article exposing (..)
|
||||||
|
|
||||||
|
-- import Cloudinary
|
||||||
|
|
||||||
import BackendTask
|
import BackendTask
|
||||||
import BackendTask.File as File
|
import BackendTask.File as File
|
||||||
import BackendTask.Glob as Glob
|
import BackendTask.Glob as Glob
|
||||||
-- import Cloudinary
|
|
||||||
import Date exposing (Date)
|
import Date exposing (Date)
|
||||||
import FatalError exposing (FatalError)
|
import FatalError exposing (FatalError)
|
||||||
import Json.Decode as Decode exposing (Decoder)
|
import Json.Decode as Decode exposing (Decoder)
|
||||||
import Pages.Url exposing (Url)
|
import Pages.Url exposing (Url)
|
||||||
import Route
|
import Route
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-- import UnsplashImage
|
-- import UnsplashImage
|
||||||
|
|
||||||
|
|
||||||
@ -27,18 +31,26 @@ contentPostsGlob folder =
|
|||||||
|> Glob.match (Glob.literal ".md")
|
|> Glob.match (Glob.literal ".md")
|
||||||
|> Glob.toBackendTask
|
|> Glob.toBackendTask
|
||||||
|
|
||||||
blogPostsGlob = contentPostsGlob "blog/"
|
|
||||||
osxPostsGlob = contentPostsGlob "osx/"
|
blogPostsGlob =
|
||||||
|
contentPostsGlob "blog/"
|
||||||
|
|
||||||
|
|
||||||
|
osxPostsGlob =
|
||||||
|
contentPostsGlob "osx/"
|
||||||
|
|
||||||
|
|
||||||
allMetadata :
|
allMetadata :
|
||||||
(String -> Route.Route)
|
(String -> Route.Route)
|
||||||
-> BackendTask.BackendTask
|
->
|
||||||
|
BackendTask.BackendTask
|
||||||
{ fatal : FatalError, recoverable : File.FileReadError Decode.Error }
|
{ fatal : FatalError, recoverable : File.FileReadError Decode.Error }
|
||||||
(List BlogPost)
|
(List BlogPost)
|
||||||
-> BackendTask.BackendTask
|
->
|
||||||
|
BackendTask.BackendTask
|
||||||
-- error
|
-- error
|
||||||
{ fatal : FatalError, recoverable : File.FileReadError Decode.Error }
|
{ fatal : FatalError, recoverable : File.FileReadError Decode.Error }
|
||||||
(List (Route.Route, ArticleMetadata))
|
(List ( Route.Route, ArticleMetadata ))
|
||||||
allMetadata routeBuilder posts =
|
allMetadata routeBuilder posts =
|
||||||
posts
|
posts
|
||||||
|> BackendTask.map
|
|> BackendTask.map
|
||||||
@ -47,7 +59,7 @@ allMetadata routeBuilder posts =
|
|||||||
|> List.map
|
|> List.map
|
||||||
(\{ filePath, slug } ->
|
(\{ filePath, slug } ->
|
||||||
BackendTask.map2 Tuple.pair
|
BackendTask.map2 Tuple.pair
|
||||||
(BackendTask.succeed <| (routeBuilder slug))
|
(BackendTask.succeed <| routeBuilder slug)
|
||||||
(File.onlyFrontmatter frontmatterDecoder filePath)
|
(File.onlyFrontmatter frontmatterDecoder filePath)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@ -59,6 +71,7 @@ allMetadata routeBuilder posts =
|
|||||||
(\( route, metadata ) ->
|
(\( route, metadata ) ->
|
||||||
if metadata.draft then
|
if metadata.draft then
|
||||||
Nothing
|
Nothing
|
||||||
|
|
||||||
else
|
else
|
||||||
Just ( route, metadata )
|
Just ( route, metadata )
|
||||||
)
|
)
|
||||||
@ -68,14 +81,21 @@ allMetadata routeBuilder posts =
|
|||||||
(\( route, metadata ) -> -(Date.toRataDie metadata.published))
|
(\( route, metadata ) -> -(Date.toRataDie metadata.published))
|
||||||
)
|
)
|
||||||
|
|
||||||
blogAllMetadata = allMetadata (\s -> Route.Blog__Slug_ { slug = s }) blogPostsGlob
|
|
||||||
osxAllMetadata = allMetadata (\s -> Route.Osx__Slug_ { slug = s }) osxPostsGlob
|
blogAllMetadata =
|
||||||
|
allMetadata (\s -> Route.Blog__Slug_ { slug = s }) blogPostsGlob
|
||||||
|
|
||||||
|
|
||||||
|
osxAllMetadata =
|
||||||
|
allMetadata (\s -> Route.Osx__Slug_ { slug = s }) osxPostsGlob
|
||||||
|
|
||||||
|
|
||||||
type alias ArticleMetadata =
|
type alias ArticleMetadata =
|
||||||
{ title : String
|
{ title : String
|
||||||
, subtitle : String
|
, subtitle : String
|
||||||
, summary : String
|
, summary : String
|
||||||
, published : Date
|
, published : Date
|
||||||
|
|
||||||
-- , image : Url
|
-- , image : Url
|
||||||
, draft : Bool
|
, draft : Bool
|
||||||
}
|
}
|
||||||
@ -111,6 +131,7 @@ frontmatterDecoder =
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-- imageDecoder : Decoder Url
|
-- imageDecoder : Decoder Url
|
||||||
-- imageDecoder =
|
-- imageDecoder =
|
||||||
-- Decode.string
|
-- Decode.string
|
||||||
|
Loading…
Reference in New Issue
Block a user