Skip to content

Commit bb3b85b

Browse files
committed
msrpc: lcid: windows language code identifiers
1 parent eefc3f6 commit bb3b85b

7 files changed

Lines changed: 1151 additions & 2 deletions

File tree

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,7 @@ Based on the [hirochachacha/go-smb2 fork](https://github.com/oiweiwei/go-smb2.fo
296296
| Spec | Description | Package |
297297
|------|-------------|---------|
298298
| [MIMICOM](https://gist.github.com/gentilkiwi/e3d9c92b93ed4bb48f7956492c1d335a) | Mimikatz Command Interface | [msrpc/mimicom](./msrpc/mimicom) |
299+
| [MS-LCID](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-lcid) | Windows Language Code Identifier (LCID) Reference | [msrpc/lcid](./msrpc/lcid) |
299300

300301
### Documentation
301302

examples/even6.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import (
3131

3232
_ "github.com/oiweiwei/go-msrpc/msrpc/erref/hresult"
3333
"github.com/oiweiwei/go-msrpc/msrpc/erref/win32"
34+
"github.com/oiweiwei/go-msrpc/msrpc/lcid"
3435
)
3536

3637
func init() {
@@ -184,7 +185,7 @@ func Metadata(ctx context.Context, cli ieventservice.EventServiceClient) {
184185

185186
meta, err := cli.GetPublisherMetadata(ctx, &ieventservice.GetPublisherMetadataRequest{
186187
PublisherID: pbl,
187-
Locale: 1033,
188+
Locale: (uint32)(lcid.LangEN_US),
188189
})
189190

190191
if err != nil {

examples/samples_with_config/even6.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import (
3030

3131
_ "github.com/oiweiwei/go-msrpc/msrpc/erref/hresult"
3232
"github.com/oiweiwei/go-msrpc/msrpc/erref/win32"
33+
"github.com/oiweiwei/go-msrpc/msrpc/lcid"
3334
)
3435

3536
var (
@@ -180,7 +181,7 @@ func Metadata(ctx context.Context, cli ieventservice.EventServiceClient) {
180181

181182
meta, err := cli.GetPublisherMetadata(ctx, &ieventservice.GetPublisherMetadataRequest{
182183
PublisherID: pbl,
183-
Locale: 1033,
184+
Locale: (uint32)(lcid.LangEN_US),
184185
})
185186

186187
if err != nil {

msrpc/lcid/gen/gen.go

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
package main
2+
3+
import (
4+
"bytes"
5+
"flag"
6+
"fmt"
7+
"go/format"
8+
"net/http"
9+
"os"
10+
"strconv"
11+
"strings"
12+
13+
"github.com/PuerkitoBio/goquery"
14+
)
15+
16+
const defaultURL = "https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-lcid/63d3d639-7fd2-4afb-abbe-0d5b5551eef8"
17+
18+
var out, pkg, url string
19+
20+
func init() {
21+
flag.StringVar(&out, "o", "-", "output file")
22+
flag.StringVar(&pkg, "pkg", "lcid", "output package")
23+
flag.StringVar(&url, "url", defaultURL, "target url")
24+
flag.Parse()
25+
}
26+
27+
type LCID struct {
28+
ID string
29+
Tag string
30+
Code string
31+
}
32+
33+
type P struct {
34+
bytes.Buffer
35+
}
36+
37+
func (p *P) P(args ...interface{}) {
38+
fmt.Fprintln(&p.Buffer, args...)
39+
}
40+
41+
func main() {
42+
lcids, err := collect(url)
43+
if err != nil {
44+
fmt.Printf("collect: %v\n", err)
45+
return
46+
}
47+
48+
pp := &P{}
49+
p := pp.P
50+
p("// Code generated by github.com/oiweiwei/go-msrpc/msrpc/lcid/gen/gen.go; DO NOT EDIT.")
51+
p("package", pkg)
52+
p()
53+
p("const", "(")
54+
55+
for _, lcid := range lcids {
56+
ui, err := strconv.ParseUint(lcid.ID, 0, 32)
57+
if err != nil {
58+
fmt.Fprintln(os.Stderr, err)
59+
os.Exit(1)
60+
}
61+
p("Lang"+lcid.Code, "LCID", "=", ui, "//", lcid.Tag, "("+lcid.ID+")")
62+
}
63+
p(")")
64+
65+
p()
66+
p("var langToTag = map[LCID]string{")
67+
for _, lcid := range lcids {
68+
p("Lang"+lcid.Code+":", strconv.Quote(strings.ToLower(lcid.Tag))+",")
69+
}
70+
p("}")
71+
72+
b, err := format.Source(pp.Bytes())
73+
if err != nil {
74+
fmt.Fprintln(os.Stderr, err)
75+
fmt.Fprintln(os.Stderr, pp.String())
76+
os.Exit(1)
77+
}
78+
79+
f := os.Stdout
80+
81+
switch out {
82+
case "-", "stdout":
83+
default:
84+
f, err = os.OpenFile(out, os.O_RDWR|os.O_TRUNC|os.O_CREATE, 0644)
85+
if err != nil {
86+
fmt.Fprintln(os.Stderr, err)
87+
os.Exit(1)
88+
}
89+
}
90+
91+
fmt.Fprintln(f, string(b))
92+
93+
}
94+
95+
func collect(url string) ([]*LCID, error) {
96+
97+
req, err := http.NewRequest(http.MethodGet, url, nil)
98+
if err != nil {
99+
return nil, fmt.Errorf("create request: %w", err)
100+
}
101+
102+
req.Header = make(http.Header)
103+
104+
resp, err := http.DefaultClient.Do(req)
105+
if err != nil {
106+
return nil, fmt.Errorf("do request: %w", err)
107+
}
108+
109+
defer resp.Body.Close()
110+
111+
if resp.StatusCode != 200 {
112+
return nil, fmt.Errorf("http: %s: %s", url, resp.Status)
113+
}
114+
115+
doc, err := goquery.NewDocumentFromReader(resp.Body)
116+
if err != nil {
117+
return nil, fmt.Errorf("parse html: %w", err)
118+
}
119+
120+
lcid := make([]*LCID, 0)
121+
122+
doc.Find(`table tr`).Each(func(i int, s *goquery.Selection) {
123+
var id, tag string
124+
s.Find("td").Each(func(j int, td *goquery.Selection) {
125+
if j == 0 {
126+
id = strings.TrimSpace(td.Text())
127+
if len(id) >= 10 {
128+
id = id[:10]
129+
} else if len(id) >= 6 {
130+
id = id[:6]
131+
}
132+
} else if j == 1 {
133+
tag, _, _ = strings.Cut(strings.TrimSpace(td.Text()), " ")
134+
tag = strings.TrimRight(tag, ",")
135+
136+
if strings.HasPrefix(id, "0x") && !ignore[strings.ToLower(tag)] {
137+
lcid = append(lcid, &LCID{ID: id, Tag: tag, Code: strings.ToUpper(strings.ReplaceAll(tag, "-", "_"))})
138+
}
139+
}
140+
141+
})
142+
})
143+
144+
return lcid, nil
145+
}
146+
147+
var ignore = map[string]bool{
148+
"unassigned": true,
149+
"reserved": true,
150+
"neither": true,
151+
"locale": true,
152+
}

0 commit comments

Comments
 (0)